HDU 2276

http://acm.hdu.edu.cn/showproblem.php?pid=2276

矩阵乘法可以解决的一类灯泡开关问题

/*

转移关系为 

now left now*

1    0    1 

1    1    0

0    1    1

0    0    0



可知F[i] = (f[i] + f[(n+i-2)%n+1]) % 2 

 

得到n*n的关系矩阵是

1 1 0 0 ... 0

0 1 1 0 ... 0

0 0 1 1 ... 0

. . . . ... 0

. . . . ... 0

. . . . ... 0

0 0 0 0 ... 1

1 0 0 0 ... 1

*/

#include <iostream> 

#include <cstdio>

#include <cstring>

#include <map>



using namespace std;



#define MOD 2



#define Mat 105 //矩阵大小

  

struct mat{//矩阵结构体,a表示内容,r行c列 矩阵从1开始  

    int a[Mat][Mat];

    int r, c;  

    mat() {  

        r = c = 0;  

        memset(a, 0, sizeof(a));  

    }  

};  



void print(mat m) {  

    //printf("%d\n", m.size);  

    for(int i = 0; i < m.r; i++) {  

        for(int j = 0; j < m.c; j++) printf("%d ", m.a[i][j]);  

        putchar('\n');  

    }  

}  

  

mat mul(mat m1, mat m2, int mod) {  

    mat ans  = mat();

    ans.r = m1.r, ans.c = m2.c;  

    for(int i = 1; i <= m1.r; i++)  

        for(int j = 1; j <= m2.r; j++)  

            if(m1.a[i][j])

                for(int k = 1; k <= m2.c; k++)  

                    ans.a[i][k] = (ans.a[i][k] + m1.a[i][j] * m2.a[j][k]) % mod;  

    return ans;  

} 



mat quickmul(mat m, int n, int mod) {  

    mat ans = mat();  

    for(int i = 1; i <= m.r; i++) ans.a[i][i] = 1;  

    ans.r = m.r, ans.c = m.c;  

    while(n) {  

        if(n & 1) ans = mul(m, ans, mod);  

        m = mul(m, m, mod);  

        n >>= 1;  

    }  

    return ans;  

}  



/* 

初始化ans矩阵 

mat ans = mat(); 

ans.r = R, ans.c = C;  

ans = quickmul(ans, n, mod); 

*/



char a[105];



int main() { 

    int m; 

    while(~scanf("%d", &m)) {

        scanf("%s", a);

        int n = strlen(a);

        mat A = mat();

        A.r = 1, A.c = n;

        for(int i = 1; i <= n; i++)

            A.a[1][i] = a[i-1] - '0';    

        mat G = mat();

        G.r = G.c = n;

        for(int i = 1; i < n; i++) {

            G.a[i][i] = G.a[i][i+1] = 1;

        }

        G.a[n][1] = G.a[n][n] = 1;

        mat ans = quickmul(G, m, MOD);

        ans = mul(A, ans, MOD);

        for(int i = 1; i <= n; i++)

            printf("%d", ans.a[1][i]);

        putchar('\n');

    }

    return 0;

}
View Code

 

你可能感兴趣的:(HDU)