hdu2276 Kiki & Little Kiki 2
传送门
题意
长度为(n(2leq nleq 100))的灯围成一个环,初始时每盏灯都有自己的状态,开着或者关着,每一秒结束后左边亮着的灯的状态会发生变化,计算(m(1leq mleq 1e8))秒之后所有灯的状态
题解
矩阵快速幂
由于每盏灯的状态都与它左边的灯和它自己有关,以(7*7)的矩阵为例,构造状态转移矩阵:
[left[egin{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 1end{matrix}
ight]
]
通过矩阵快速幂,计算(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("
");
}
return 0;
}