您的位置:首页 > 其它

fzu 1692 Key problem(循环同构矩阵o(n^2)优化乘法)

2014-04-24 18:37 323 查看
fzu 1692 Key problem

此题和这个题差不多一个意思

这个题关键是优化循环同构矩阵的乘法,不然会超时,一般矩阵乘法的复杂度是O(n^3),稀疏矩阵情况会好一些

循环同构矩阵就是说矩阵的一行可以从上一行推出来,这样做矩阵乘法的时候就只需要先O(n^2)求出第一行,在O(n^2)通过上一行求出剩下的

此题有误,题中的L应为R,R应为L

#include<stdio.h>
#include<string.h>
#define MAXN 105
#define ll __int64
struct matrix
{
ll m[MAXN][MAXN];
};
int n,mod;
matrix multi(const matrix &a,const matrix &b)
{
matrix ans;
for(int i=0;i<n;i++)
{
ans.m[0][i]=0;
for(int j=0;j<n;j++)
{
ans.m[0][i]+=a.m[0][j]*b.m[j][i];
}
ans.m[0][i]%=mod;
}

for(int i=1;i<n;i++)
for(int j=0;j<n;j++)
{
ans.m[i][j]=ans.m[i-1][(j+n-1)%n];
}
return ans;
}
matrix pow(matrix a,int k)
{
matrix ans;
memset(&ans,0,sizeof(ans));

for(int i=0;i<n;i++) ans.m[i][i]=1;
while(k)
{
if(k&1) ans=multi(ans,a);
a=multi(a,a);
k>>=1;
}
return ans;
}
int b[MAXN];
int main()
{
matrix a;
int cas;
int k,l,r;
scanf("%d",&cas);
while(cas--)
{
scanf("%d%d%d%d%d",&n,&k,&l,&r,&mod);
for(int i=0;i<n;i++) scanf("%d",&b[i]);
memset(&a,0,sizeof(a));
for(int i=0;i<n;i++)
{
a.m[i][i]=1;
a.m[i][(i+n-1)%n]=r;
a.m[i][(i+1)%n]=l;
}
a=pow(a,k);
ll ans;
for(int i=0;i<n;i++)
{
ans=0;
for(int j=0;j<n;j++)
{
ans+=a.m[i][j]*b[j];
ans%=mod;
}
if(i) printf(" ");
printf("%I64d",ans%mod);
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息