HDU 2276 Kiki & Little Kiki 2 (矩阵快速幂)

来源:互联网 发布:mac ntfs读写插件 免费 编辑:程序博客网 时间:2024/05/17 01:20

大意:有01串分别代表灯的状态(关闭,打开),当当前灯的左边灯是1,那么当前灯状态改变,否则不变。

思路:以其中的两个灯的状态来考虑。
0 0
0 1
1 0
1 1

一共四种状态,最后两种状态才能使当前灯状态改变,那么可以发现当前灯的状态可以用f[i] = (f[i]+f[(i+n-1)%n]) % 2来表示(第一个灯的前边是最后一个灯,其中f[i]为0 | 1)。那么就有了递推关系式。

接着上面的四种灯的关系状态有
左边——当前——–变化
1 ——— 1————0
1 ———0————-1
0 ——— 1————-1
0 ———0————-0
所以关系矩阵就有了

这里写图片描述

然后用初始状态乘以连乘后的矩阵。

#include<map>#include<cmath>#include<queue>#include<cmath>#include<string>#include<cstdio>#include<stack>#include<iostream>#include<cstring>#include<algorithm>#define inf 0x3f3f3f3f#define eps 1e-8#define ls l,mid,rt<<1#define rs mid+1,rt,rt<<1|1#define LL __int64using namespace std;const int mod = 2;int n;struct node{    int r[110][110];}q,now;char s[10000];int tt[110];node matrix_pow(node a,node b){    int i,j,k;    node t;    memset(t.r,0,sizeof(t.r));    for(k = 0;k < n;++ k){        for(i = 0 ;i < n;++ i){            for(j = 0;j < n;++ j){                t.r[i][j] = (t.r[i][j]+ (a.r[i][k]*b.r[k][j]))%mod;            }        }    }    return t;}node so(node q,int m){    int i,j,k;    node tmp;    memset(tmp.r,0,sizeof(tmp.r));    for(i = 0;i < n;++ i )            tmp.r[i][i] = 1;    while(m){        if(m&1)            tmp = matrix_pow(tmp,q);        q = matrix_pow(q,q);        m = m >> 1;    }   return tmp;}int main(){    int m,k,i,j;    while(~scanf("%d",&m)){        memset(q.r,0,sizeof(q.r));        scanf("%s",s);        int len=strlen(s);        n=len;        for(i = 0;i < len;++ i){            tt[i] = s[i] - '0';        }        q.r[0][len-1] = q.r[len-1][len-1] = 1;        j = 0;        for(i = 0;i < len-1 ; ++ i,++j){            if(j+1 <= len)                q.r[i][j] = q.r[i+1][j] = 1;        }        q = so(q,m);        int cnt = 0,o;        for(cnt = 0;cnt < len; ++ cnt){            o=0;            for(i = 0;i < len;++ i){                o = (o + tt[i]*q.r[cnt][i])%mod;            }printf("%d",o);        }        cout<<endl;    }    return 0;}
0 0
原创粉丝点击