http://ac.jobdu.com/problem.php?id=1081
递推数列
同理Fibonacci数列也可以使用矩阵来求,二分求矩阵的n次幂可以达到O(N*lgN)的时间复杂度。。
(2^n)%k的问题也可以使用这个二分的方法来求解。。
#include<iostream>
#include<cstdio>
using namespace std;
struct Matrix
{
int a[2][2];
};
Matrix E;
void InitE(int size) //初始化单位矩阵
{
for(int i=0;i<size;i++)
{
for(int j=0;j<size;j++)
E.a[i][j]=(i==j);
}
}
Matrix MatrixMul(Matrix a,Matrix b) //两矩阵相乘
{
Matrix c;
int i,j,k;
for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
c.a[i][j]=0;
for(k=0;k<2;k++)
{
c.a[i][j] += ((a.a[i][k]%10000)*(b.a[k][j]%10000));
c.a[i][j]%=10000;
}
}
}
return c;
}
Matrix MatrixPow(Matrix a,int n) //矩阵快速二分求n次幂
{
Matrix t=E;
while(n>0)
{
if(1&n) //n是奇数
t=MatrixMul(t,a);
a=MatrixMul(a,a);
n >>= 1;
}
return t;
}
int main(void)
{
int a0,a1,p,q,k;
Matrix matrix,m;
InitE(2);
while(scanf("%d %d %d %d %d",&a0,&a1,&p,&q,&k)!=EOF)
{
if(!k) //这两个特殊情况当时未考虑,导致多次WA
printf("%d\n",a0);
else if(k==1)
printf("%d\n",a1);
else
{
matrix.a[0][0]=p; //构造初始矩阵
matrix.a[0][1]=q;
matrix.a[1][0]=1;
matrix.a[1][1]=0;
m=MatrixPow(matrix,k-1);
printf("%d\n",(m.a[0][0]*a1+m.a[0][1]*a0)%10000);
}
}
return 0;
}
http://acm.hdu.edu.cn/showproblem.php?pid=2035快速二分求幂A^B
#include<iostream>
using namespace std;
#include<stdio.h>
inline int Pow(int x,int k,int mod) //快速二分求幂x^k
{
int ans=1;
while(k)
{
if(k&1)
{
ans*=x;
if(ans>=mod)
ans%=mod;
}
x*=x;
if(x>=mod)
x%=mod;
k>>=1;
}
return ans;
}
int main(void)
{
int a,b;
while(scanf("%d %d",&a,&b) && a && b)
{
printf("%d\n",Pow(a,b,1000));
}
return 0;
}