poj 3150
矩阵乘法,运用循环矩阵性质。
代码:
#include<iostream> #include<fstream> #include<cmath> using namespace std; long long map[501][501],map1[501][501],map2[501][501]; long long m,d; long long k; long long a[501],b[501]; int n; void solve(long long k){ long long i,j; if(k==1) { for(i=1;i<=n;i++) for(j=1;j<=n;j++) map1[i][j]=map[i][j]; } else { solve(k/2); for(i=1;i<=n;i++) { map2[1][i]=0; for(j=1;j<=n;j++) { map2[1][i]+=map1[1][j]*map1[j][i]; map2[1][i]%=m; } } for(i=2;i<=n;i++) { map2[i][1]=map2[i-1][n]; for(j=2;j<=n;j++) map2[i][j]=map2[i-1][j-1]; } if(k/2*2==k) { for(i=1;i<=n;i++) for(j=1;j<=n;j++) map1[i][j]=map2[i][j]; } else { for(i=1;i<=n;i++) { map1[1][i]=0; for(j=1;j<=n;j++) { map1[1][i]+=map2[1][j]*map[j][i]; map1[1][i]%=m; } } for(i=2;i<=n;i++) { map1[i][1]=map1[i-1][n]; for(j=2;j<=n;j++) map1[i][j]=map1[i-1][j-1]; } } } } void read(){ // ifstream cin("in.txt"); int i,j; while(cin>>n>>m>>d>>k) { for(i=1;i<=n;i++) // cin>>a[i]; scanf("%lld",&a[i]); memset(map,0,sizeof(map)); for(i=1;i<=n;i++) { for(j=1;j<=n;j++) if(min(abs(i-j),n-abs(i-j))<=d) map[i][j]=1; } solve(k); for(i=1;i<=n;i++) { b[i]=0; for(j=1;j<=n;j++) { b[i]+=a[j]*map1[j][i]; b[i]%=m; } } for(i=1;i<=n;i++) cout<<b[i]<<' '; cout<<endl; } } int main(){ read(); return 0; }