很妙啊……发现状态转移矩阵每一行都可以由上一行平移得到,每次只算第一行然后平移,(O(n^3)) 就变成了 (O(n^2))。
#include <iostream>
#include <cstdio>
using namespace std;
int n, k;
struct Matrix{
int num[205][205];
Matrix operator*(const Matrix &x)const{
Matrix re;
for(int i=1; i<=n; i++){
re.num[1][i] = 0;
for(int j=1; j<=n; j++)
re.num[1][i] = (re.num[1][i]+num[1][j]*x.num[j][i])%100;
}
for(int i=2; i<=n; i++)
for(int j=1; j<=n; j++)
re.num[i][j] = re.num[i-1][(j-2+n)%n+1];
return re;
}
}dan, yua, zhu;
int main(){
cin>>n>>k;
for(int i=1; i<=n; i++){
scanf("%d", &yua.num[1][i]);
dan.num[i][i] = 1;
zhu.num[i][i] = zhu.num[i][(i-2+n)%n+1] = 1;
}
while(k){
if(k&1) dan = dan * zhu;
zhu = zhu * zhu;
k >>= 1;
}
yua = yua * dan;
for(int i=1; i<=n; i++)
printf("%d ", yua.num[1][i]);
printf("
");
return 0;
}