列表

详情


NC15967. 矩阵

描述

给定两个巨大的方块矩阵A和B (行数高达 7000).请输出A x B 的运算结果,且时限只有 2s。
哈哈!对矩阵乘法的演进历史有些涉猎的人,应该能感受到在 某CPC 上出现这样的题目有多不合理。

为了使这个问题成为可能(?),我们将减小I / O大小。
现在,给定a,b,c,d的四个种子可以通过Xorshift随机数生成器生成输入矩阵。
这里是通过随机数生成器来产生矩阵的实现:
uint32_t x, y, z, w; uint32_t xorshift() {     uint32_t t = x;     t ^= t << 11;     t ^= t >> 8;     x = y; y = z; z = w;     w ^= w >> 19;     w ^= t;     return w & ((1 << 24) - 1); } void getInputMatrix(     int n, uint32_t matrix[][7000],     uint32_t a, uint32_t b, uint32_t c, uint32_t d ) {     x = a; y = b; z = c; w = d;     for (int i = 0; i < n; ++i) {         for (int j = 0; j < n; ++j) {             matrix[i][j] = xorshift();         }     } }

另外,您应该将输出矩阵传递给哈希函数(hash function)。
我们会给你另一个数字p来做这件事。
这里是哈希函数的实现。
const int MOD = 1000000007; int hash(int n, long long matrix[][7000], int p) {     long long v = 0;     for (int i = 0; i < n; ++i) {         for (int j = 0; j < n; ++j) {             v *= p;             v += matrix[i][j];             v %= MOD;         }     }     return v; }
P.S. 不懂 C++语法的同学们就抱歉啦~

输入描述

输入只包含一行,包含十个整数n,Aa,Ab,Ac,Ad,Ba,Bb,Bc,Bd,p。
矩阵A是通过n,Aa,Ab,Ac,Ad构建getInputMatrix()的。
矩阵B是通过n,Ba,Bb,Bc,Bd构建getInputMatrix()的。
p是哈希函数。

输出描述

令 C = A * B, C 是A矩阵乘以 B 的结果
请输出一个整数,它是 hash(n,C,p) 的结果

示例1

输入:

1 2 3 4 5 6 7 8 9 10

输出:

50873769

示例2

输入:

2 3 4 5 6 7 8 9 10 11

输出:

891416296

示例3

输入:

7000 7001 7002 7003 7004 7005 7006 7007 7008 7009

输出:

276810293

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 821ms, 内存消耗: 192540K, 提交时间: 2022-08-18 13:42:14

#include<bits/stdc++.h>

using namespace std;

typedef long long LL;
inline unsigned int in()
{
	char ch=getchar();
	unsigned int f=1,x=0;
	while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
	return f*x;
}

//need changing
const int inf=(1<<30);
const int mod=1e9+7;
const int N=7010;
unsigned int n,a[N][N],p;

unsigned int x, y, z, w;
unsigned int xorshift()
{     
	unsigned int t = x;
	t ^= t << 11;
	t ^= t >> 8; 
	x = y; y = z; z = w;     
	w ^= w >> 19;     
	w ^= t;     
	return w & ((1 << 24) - 1); 
} 

LL ww[N];

LL qmi(LL a,LL b)
{
	LL ret=1;
	while(b)
	{
		if(b&1) ret=ret*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return ret;
}

int main()
{
	n = in();
	unsigned int Aa = in(),Ab = in(),Ac = in(),Ad = in(),Ba = in(),Bb = in(),Bc = in(),Bd = in();
	p = in();
	
	x = Aa; y = Ab; z = Ac; w = Ad;     
	for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)  
            a[i][j] = xorshift();
    
	x = Ba; y = Bb; z = Bc; w = Bd;     
	LL ans=0;
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < n; ++j)
		{
			ww[i] *= p;
			ww[i] += xorshift();
			ww[i] %= mod;
		}
	}

	for (int i = 0; i < n; ++i)
	{
		LL v = qmi(p, n * (n - 1 - i));
		for (int j = 0; j < n; ++j)
		{
			LL ret = 1ll * a[i][j] * ww[j] % mod;
			ret = ret * v %mod;
			ans += ret ;
			ans %= mod ;
		}
	}
	printf("%lld\n",ans);
	return 0;
}

C++14(g++5.4) 解法, 执行用时: 641ms, 内存消耗: 616K, 提交时间: 2018-08-11 18:08:18

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=7000;
const int mod = 1000000007;
int A[maxn],B[maxn];
uint32_t x, y, z, w;
uint32_t xorshift()
{
    uint32_t t = x;
    t ^= t << 11;
    t ^= t >> 8;
    x = y; y = z; z = w;
    w ^= w >> 19;
    w ^= t;
    return w & ((1 << 24) - 1);
}
int add(int a,int b)
{
    return a+b>=mod?a+b-mod:a+b;
}
int mul(int a,int b)
{
    ll z=1ll*a*b;
    return z-z/mod*mod;
}
int Pow(int a,int b)
{
    int ans=1;
    while(b)
    {
        if(b&1)ans=mul(ans,a);
        a=mul(a,a);
        b>>=1;
    }
    return ans;
}
int main()
{
    int n,p;
    uint32_t Aa,Ab,Ac,Ad,Ba,Bb,Bc,Bd;
    scanf("%d%u%u%u%u%u%u%u%u%d",&n,&Aa,&Ab,&Ac,&Ad,&Ba,&Bb,&Bc,&Bd,&p);
    x = Aa; y = Ab; z = Ac; w = Ad;
    int P=Pow(p,n*(n-1)),invp=Pow(Pow(p,n),mod-2);
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
            A[j]=add(A[j],mul(xorshift(),P));
        P=mul(P,invp);
    }
    x = Ba; y = Bb; z = Bc; w = Bd;
    P=Pow(p,n-1),invp=Pow(p,mod-2);
    for(int i=0;i<n;i++)
        {
            int PP=P;
            for(int j=0;j<n;j++)
            B[i]=add(B[i],mul(xorshift(),PP)),PP=mul(PP,invp);
        }
    int ans=0;
    for(int k=0;k<n;k++)ans=add(ans,mul(A[k],B[k]));
    printf("%d\n",ans);
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 372ms, 内存消耗: 612K, 提交时间: 2018-10-08 12:52:35

#include<cstdio>
using namespace std;
typedef long long ll;
typedef unsigned uint32_t;
const int maxn=7000;
uint32_t x,y,z,w;
uint32_t xorshift() 
{
    uint32_t t=x;
    t^=t<<11;
    t^=t>>8;
    x=y;y=z;z=w;
    w^=w>>19;
    w^=t;
    return w&((1<<24)-1);
}
#define mod 1000000007
int mul(int x,int y)
{
	ll z=1ll*x*y;
	return z-z/mod*mod;
}
int add(int x,int y)
{
	x+=y;
	if(x>=mod)x-=mod;
	return x;
}
uint32_t Aa,Ab,Ac,Ad,Ba,Bb,Bc,Bd,p;
int n,f[maxn],g[maxn],A[maxn],B[maxn];
int main()
{
	scanf("%d%u%u%u%u%u%u%u%u%u",&n,&Aa,&Ab,&Ac,&Ad,&Ba,&Bb,&Bc,&Bd,&p);
	p%=mod;
	f[0]=g[0]=1;
	for(int i=1;i<n;i++)f[i]=mul(f[i-1],p);
	p=mul(f[n-1],p);
	for(int i=1;i<n;i++)g[i]=mul(g[i-1],p);
	x=Aa,y=Ab,z=Ac,w=Ad;
	for(int i=0;i<n;i++)
		for(int k=0;k<n;k++)
			A[k]=add(A[k],mul(xorshift(),g[n-1-i]));
	x=Ba,y=Bb,z=Bc,w=Bd;
	for(int k=0;k<n;k++)
		for(int j=0;j<n;j++)
			B[k]=add(B[k],mul(xorshift(),f[n-1-j]));
	int ans=0;
	for(int k=0;k<n;k++)ans=add(ans,mul(A[k],B[k]));
	printf("%d\n",ans);
	return 0;
}

上一题