题意看不懂加题目想不通,很菜。
n<=500个数围城环,每次操作对每个数Ai把与i在环上相距不超过d<n/2(包括Ai)的数加起来取模m<=1e6,求K<=1e7次操作后的环。
存在递推关系,构造矩阵吧!比如样例一很丑。
于是矩阵快速幂,n*n*n*logK,很慢。
这个矩阵比较奇怪,每一行都是上一行右移一位,而且每一行和每一列长得一样。也就是说我们只保存第一行就能知道整个矩阵长什么样。
而我们的时间主要浪费在a的相乘上,所以a只维护一行,计算答案时把a还原,更新一行的“a”时亦然,具体见代码。
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #include<math.h> 5 //#include<iostream> 6 using namespace std; 7 8 int n,mod,d,K; 9 #define maxn 511 10 int a[maxn],b[maxn]; 11 void mul(int *a,int *b,int *ans) 12 { 13 int t[maxn]; 14 memset(t,0,sizeof(t)); 15 for (int i=1;i<=n;i++) 16 for (int j=1;j<=n;j++) 17 t[i]=(t[i]+1ll*a[j-i+1+(j-i>=0?0:n)]*b[j]%mod)%mod; 18 for (int i=1;i<=n;i++) ans[i]=t[i]; 19 } 20 int main() 21 { 22 scanf("%d%d%d%d",&n,&mod,&d,&K); 23 for (int i=1;i<=n;i++) scanf("%d",&b[i]); 24 memset(a,0,sizeof(a)); 25 for (int i=1;i<=d+1;i++) a[i]=1; 26 for (int i=n;i>n-d;i--) a[i]=1; 27 while (K) 28 { 29 if (K&1) mul(a,b,b); 30 mul(a,a,a); 31 K>>=1; 32 } 33 for (int i=1;i<=n;i++) printf("%d ",b[i]); 34 return 0; 35 }