nuc 第二届山西省大学生程序设计大赛 魔力手环

problem

很妙啊……发现状态转移矩阵每一行都可以由上一行平移得到,每次只算第一行然后平移,\(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("\n");
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/poorpool/p/8856790.html