hdu_2276_构造矩阵_快速幂乘

来源:互联网 发布:vscode debug npm 编辑:程序博客网 时间:2024/05/17 04:14

/*
非递归的二分用3^n模拟,比如下面代码的p,a分别出现的是:3 3^2,3^3 3^4,3^7 3^8,3^15 3^16 ....3^i-1 3^i(i=2^k)

a1=(a1+an)%2

a2=(a1+a2)%2

a3=(a1+a2)%2.............ai=(a(i-1)+ai)%2;

有这种关系,我们想到用矩阵去运算,先要构造一个矩阵!

| 1 0 0 0 ....1 |

| 1 1 0 0.....0 |    

| 0 1 1 0 ....0| 

     ......
*/

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;

struct mat
{
    int m[100][100];
};

int m;
int len;

mat product(mat a,mat b)
{
    mat c;
    int i,j,k;
    memset(c.m,0,sizeof(c.m));
    for(i=0;i<len;i++)
        for(j=0;j<len;j++)
        {
            for(k=0;k<len;k++)
                c.m[i][j]+=a.m[i][k]*b.m[k][j];
            c.m[i][j]%=2;
        }
        return c;
}

mat div(mat a,int x)        //如果用递归解决的话就爆内存,只能用非递归,而且还要注意用二分法,非递归的话可以用2^7模拟,
{
    mat p;        //p为单位矩阵
    int i,j;
    for(i=0;i<len;i++)
        for(j=0;j<len;j++)
            p.m[i][j]=(i==j);
    while(x)
    {
        if(x&1)
            p=product(p,a);
        x>>=1;
        a=product(a,a);
    }
    return p;
}

int main()
{
    char s[100],ans[100];
    mat a;
    int c[100],d[100];
    int i,j,k;
    while(scanf("%d",&m)!=EOF)
    {
        scanf("%s",s);
        len=strlen(s);
        memset(a.m,0,sizeof(a.m));
        a.m[0][len-1]=1;
        for(i=0;i<len;i++)
            for(j=0;j<len;j++)
                if(i==j||i-1==j)
                    a.m[i][j]=1;
                mat b;
                b=div(a,m);
                for(i=0;i<len;i++)
                    c[i]=s[i]-'0';
                memset(d,0,sizeof(d));
                for(i=0;i<len;i++)
                    for(j=0;j<len;j++)
                        d[i]=(d[i]+b.m[i][j]*c[j])%2;
                    for(i=0;i<len;i++)
                        ans[i]=d[i]+'0';
                    ans[len]='/0';
                    printf("%s/n",ans);
    }
    return 0;
}


原创粉丝点击