圆盘自动机 cell
一个n-m圆盘自动机,包含n个排列成一圈的方格,它们按1至n编号。每个方格中有一个整数,范围[0,m-1] 。圆盘会进行d操作,每次d操作会使得每个方格中的数同时变换,变换为与其位置差不超过d的所有圆盘中数的和模m的结果(注意圆盘排成一圈首尾相连)。
一个5-3自动机进行一次1操作后的状态如下:

给定一个n-m自动机的初始状态,以及n,m,d,k。问这个自动机进行k次d操作之后的状态。
输入格式
第一行包含n,m,d,k . 第二行包含n个整数,范围[0,m-1]
输出格式
一行n个整数,为所求的操作后状态。
样例
样例输入
5 3 1 1
1 2 2 1 2
样例输出
2 2 2 2 1
数据范围与提示
【样例输入二】
5 3 1 10
1 2 2 1 2
【样例输出二】
2 0 0 2 2
【数据范围】
<span ,"serif""> 对于30%的数据,n<=100,d<=100,k<=100 ;
对于60%的数据,n<=100 ;
对于100%的数据,1<=n<=500,1<=m<=1 000 000,0<=d<=n/2,1<=k<=10 000 000 。
solution
k是10^9,考虑矩阵乘法。
n是500,似乎会T。
有个高级的东西叫循环矩阵。
如果一个矩阵的下一行是由上一行左移得到,那么就可以用。
我们只记录第一行。
考虑c=a*b
c[1]=a[1][1]*b[1][1]+a[1][2]*b[2][1]+a[1][3]*b[3][1]+a[1][4]*b[4][1]
=a[1]*b[1]+a[2]*b[4]+a[3]*b[3]+a[4]*b[2]
c[2]=a[1][1]*b[1][2]+a[1][2]*b[2][2]+a[1][3]*b[3][2]+a[1][4]*b[4][2]
=a[1]*b[2]+a[2]*b[1]+a[3]*b[4]+a[4]*b[3]
c[(i+j-2)%n+1]=a[i]*b[j]
node operator *(node ax,node bx){ node c;c.cle(); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ int x=(i+j-2)%n+1; c.v[x]=(c.v[x]+ax.v[i]*bx.v[j])%mod; } return c; } //O(n^2)
还有一个性质:循环矩阵相乘还是循环矩阵。
这样就n^2解决了