hdu2276 矩阵快速幂

hdu2276 Kiki & Little Kiki 2
传送门
题意
长度为\(n(2\leq n\leq 100)\)的灯围成一个环,初始时每盏灯都有自己的状态,开着或者关着,每一秒结束后左边亮着的灯的状态会发生变化,计算\(m(1\leq m\leq 1e8)\)秒之后所有灯的状态
题解
矩阵快速幂
由于每盏灯的状态都与它左边的灯和它自己有关,以\(7*7\)的矩阵为例,构造状态转移矩阵:

\[\left[\begin{matrix}1\ 1\ 0\ 0\ 0\ 0\ 0\\0\ 1\ 1\ 0\ 0\ 0\ 0\\0\ 0\ 1\ 1\ 0\ 0\ 0\\0\ 0\ 0\ 1\ 1\ 0\ 0\\0\ 0\ 0\ 0\ 1\ 1\ 0\\0\ 0\ 0\ 0\ 0\ 1\ 1\\1\ 0\ 0\ 0\ 0\ 0\ 1\end{matrix}\right] \]

通过矩阵快速幂,计算\(m\)秒后所有位置的奇偶性,也就是灯的状态变化情况

#include<iostream>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<cstring>
#include<string>
#include<sstream>
#include<cmath>
#include<ctime>
#include<climits>
#include<algorithm>
#define LL long long
#define PII pair<int,int>
#define PLL pair<LL,LL>
#define pi acos(-1.0)
#define eps 1e-6
#define lowbit(x) x&(-x)
using namespace std;

int m;
char s[110];
struct Matrix{
    int mat[110][110];
    int r,c;
    Matrix(){
        memset(mat,0,sizeof(mat));
    }
};

Matrix mul(Matrix A,Matrix B){
    int a=A.r,b=B.c,c=A.c;
    Matrix res;
    res.r=a;
    res.c=b;
    for(int i=0;i<a;i++){
        for(int k=0;k<c;k++){
            if(A.mat[i][k]){
                for(int j=0;j<b;j++){
                    res.mat[i][j]=(res.mat[i][j]+A.mat[i][k]*B.mat[k][j]&1)&1;
                }
            }
        }
    }
    return res;
}

Matrix qp(Matrix A,int k){
    int a=A.r;
    Matrix res;
    res.r=res.c=a;
    for(int i=0;i<a;i++) res.mat[i][i]=1;
    while(k){
        if(k&1) res=mul(res,A);
        A=mul(A,A);
        k>>=1;
    }
    return res;
}

int main(){
    while(~scanf("%d",&m)){
        scanf("%s",s);
        int n=strlen(s);
        Matrix matrix;
        matrix.r=matrix.c=n;
        matrix.mat[n-1][0]=1;
        matrix.mat[0][0]=1;
        for(int i=1;i<n;i++){
            matrix.mat[i-1][i]=1;
            matrix.mat[i][i]=1;
        }
        matrix=qp(matrix,m);
        Matrix light;
        light.r=1;
        light.c=n;
        for(int j=0;j<n;j++){
            light.mat[0][j]=s[j]-'0';
        }
        light=mul(light,matrix);
        for(int j=0;j<n;j++) printf("%d",light.mat[0][j]);
        printf("\n");
    }
    return 0;
}
posted @ 2020-08-29 21:38  fxq1304  阅读(26)  评论(0编辑  收藏  举报