起初直接有矩陣乘法做,結果TLE。後來參考網上代碼,發現他們巧妙利用轉移矩陣的性質。從而降低複雜度。
轉移矩陣的下一列是前一列的下移而來。因次計算出第一列,其餘的就可推出。
code:
#include<stdio.h>
#include<string.h>
int n,m,k,d;
__int64 ans[510]={0};
__int64 E[501];
int multiply(__int64 (*A),__int64 (*B))
{
int i,j,t;
__int64 C[502]={0};
for(i=0;i<n;i++)
{
j=(n-i)%n;
for(t=0;t<n;t++)
{
C[i]+=A[t]*B[j];
j=(j+1)%n;
}
}
for(i=0;i<n;i++)
A[i]=C[i]%m;
return 1;
}
int erfen()
{
while(k)
{
if(k&1)multiply(ans,E);
multiply(E,E);
k>>=1;
}
return 0;
}
int main()
{
int i,cnt=0;
while(EOF!=scanf("%d%d%d%d",&n,&m,&d,&k))
{
for(i=0;i<n;i++)
scanf("%I64d",&ans[i]);
memset(E,0,sizeof(E));
for(E[0]=i=1;i<=d;i++)
{
E[i]=E[n-i]=1;
}
erfen();
for(i=0;i<n;i++)
printf("%I64d ",ans[i]);
printf("/n");
}
return 0;
}