poj 3070 Fibonacci
模板:矩阵快速幂。求矩阵的n次方结果对MOD取余
http://poj.org/problem?id=3070
#include<cstdio>
#include<cstring>
const int MOD=10000;
struct matrix
{
int v[3][3];
}ans;
matrix mul(matrix a,matrix b)
{
matrix temp;
memset(temp.v,0,sizeof(temp.v));
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
{
for(int k=1;k<=2;k++)
temp.v[i][j]+=(a.v[i][k]*b.v[k][j])%MOD;
}
return temp;
}
matrix pow(matrix a,int n)
{
matrix res;
for(int i=1;i<=2;i++)
res.v[i][i]=1;
res.v[1][2]=res.v[2][1]=0;
while(n)
{
if(n&1)
res=mul(a,res);
a=mul(a,a);
n>>=1;
}
return res;
}
int main()
{
int n;
while(~scanf("%d",&n)&&n!=-1)
{
matrix a;
a.v[1][1]=1;
a.v[1][2]=1;
a.v[2][1]=1;
a.v[2][2]=0;
ans=pow(a,n);
printf("%d\n",ans.v[1][2]%MOD);
}
}
HDU 2267 Kiki & Little Kiki 2
http://acm.hdu.edu.cn/showproblem.php?pid=2276
题意:给定包含n个只含01的字符串。字符串每次可以变化,变化规则是当前位置的左侧是‘1’,那么就要改变(1->0或0->1),是0无需改变。最左端的左侧是最右端。求m次变化后的字符串。
变化m次后的字符串F m = ( a(m,1) ,a(m,2) , a(m,3)...a(m,n))
变化m-1次Fm-1 = ( a(m-1,1), a(m-1,2),...,a(m-1,n) )
均为n*n方阵
a(m,1) = ( a(am-1,1)+a(m-1,n) )%2
#include<cstdio>
#include<cstring>
const int maxn = 1e8+10;
const int maxN = 101;
char f[101];
int m[101][101];
int res[101][101];
int n;
void print(int m[][maxN]);
void mul(int c[][maxN],int a[][maxN],int b[][maxN])//c=a*b
{
int t[101][101];
memset(t,0,sizeof(t));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
t[i][j]+=(a[i][k]*b[k][j])%2;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
c[i][j]=t[i][j]%2;
}
}
void pow(int N)
{
memset(res,0,sizeof(res));
for(int i=1;i<=n;i++)res[i][i]=1;
while(N)
{
if(N&1)
mul(res,m,res);
mul(m,m,m);
N>>=1;
}
}
void print(int m[][maxN])
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
printf("%d ",res[i][j]);
printf("\n");
}
}
int main()
{
int M;
while(~scanf("%d",&M))
{
scanf("%s",f);
int a[101];
n=strlen(f);
for(int i=0;i<n;i++)
{
a[i+1]=f[i]-'0';
}
memset(m,0,sizeof(m));
for(int i=1;i<=n;i++)
{
if(i!=n)
m[i][i]=m[i][i+1]=1;
else
{
m[i][1]=m[i][n]=1;
}
}
pow(M);
// print(res);
for(int i=1;i<=n;i++)
{
int s=0;
for(int j=1;j<=n;j++)
{
s=(s+a[j]*res[j][i])%2;
}
if(i!=n)
printf("%d",s%2);
else
printf("%d\n",s%2);
}
}
}