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;
}
非递归的二分用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;
}
相关文章推荐
- hdu 2276 Kiki & Little Kiki 2 矩阵快速幂
- HDU 2276 Kiki & Little Kiki 2 矩阵快速幂
- HDU 2276 Kiki & Little Kiki 2 矩阵构造
- hdu 2276(矩阵快速幂)
- hdu 2276 Kiki & Little Kiki 2矩阵快速幂
- HDU 2276 & FZU 1692 (矩阵快速幂+循环同构优化)
- hdu 1005 Number Sequence 构造矩阵 + 矩阵快速幂
- hdu 2276 Kiki & Little Kiki 2(矩阵快速幂)
- hdu A Simple Math Problem 1757 矩阵的构造和快速幂
- HDU 2276 Kiki & Little Kiki 2 矩阵构造和乘法
- HDU 2276(数论,构造二分矩阵)
- HDU 2276 矩阵快速幂
- Kiki & Little Kiki 2 - HDU 2276 - 矩阵快速幂
- HDU 2256 Problem of Precision 解题报告(矩阵快速幂 + 构造)
- HDU 2276 Kiki & Little Kiki 2 (矩阵快速幂)
- hdu 2276 矩阵快速幂&&循环矩阵优化
- HDU 2276 Kiki & Little Kiki 2(矩阵快速幂)
- hdu 5015 233 Matrix 线性序列构造矩阵快速幂
- hdu 2276(矩阵快速幂)
- HDU 1757 A Simple Math Problem(矩阵快速幂构造)