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;
}
浙公网安备 33010602011771号