您的位置:首页 > 其它

hdu_2276_构造矩阵_快速幂乘

2011-01-21 01:57 603 查看
/*

非递归的二分用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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: