1.普通快速幂
快速幂模板:
1 int Quick_pow(int a,int b) 2 { 3 int ans=1; 4 while(b){ 5 if(b&1) 6 ans=ans*a; 7 a=a*a; 8 b>>=1; 9 } 10 return ans; 11 }
矩阵快速幂模板
1 matrix Quick_pow(matrix a,long long k) 2 { 3 matrix ans; 4 ans.init(); 5 while(k) 6 { 7 if(k&1) ans=mul(ans,a); 8 a=mul(a,a); 9 k>>=1; 10 } 11 return ans; 12 }
2.快速幂+求模
快速幂求模模板:
int Quick_pow(int a,int b,int c)//a-底数,b-指数,c-mod,
{
int ans=1; a=a%c;//先将a化为a的mod的范围内
while(b){
if(b&1) ans=1ll*ans*a%c;
a=1ll*a*a%c;//a的模乘以b的模的mo等于a乘积的模
b>>=1;//(a*b)%c=(a%c)*(b%c)%c
}
return ans;
}
POJ1995:Raising Modulo Numbers
板题快速幂求模地址
1 #include<cstdio> 2 int Quick_pow(int a,int b,int c) 3 { 4 int ans=1; 5 a=a%c; 6 while(b){ 7 if(b&1) 8 ans=(ans*a)%c; 9 a=(a*a)%c; 10 b>>=1; 11 } 12 return ans; 13 } 14 int main() 15 { 16 int t,h,c; 17 scanf("%d",&t); 18 while(t--){ 19 int sum=0,a,b; 20 scanf("%d",&c); 21 scanf("%d",&h); 22 for(int i=0;i<h;++i) 23 { 24 scanf("%d %d",&a,&b); 25 sum=(sum+Quick_pow(a,b,c))%c; 26 } 27 printf("%d ",sum); 28 } 29 return 0; 30 }
3.矩阵快速幂
a.矩阵快速幂板题
POJ3070:Fibonacci
链接
1 #include<cstdio> 2 #include<cstring> 3 const int maxn=2;//阶数 4 //const int mod=1000000007; 5 const int mod=10000; 6 int n; 7 struct matrix{ 8 int a[100][100]; 9 void init() 10 { 11 memset(a,0,sizeof(a)); 12 for(int i=0;i<maxn;++i) a[i][i]=1; 13 } 14 }; 15 16 matrix mul(matrix x,matrix y) 17 { 18 matrix c; 19 memset(c.a,0,sizeof(c.a)); 20 for(int i=0;i<maxn;++i){ 21 for(int j=0;j<maxn;++j){ 22 for(int k=0;k<maxn;++k){ 23 c.a[i][j]+=x.a[i][k]*y.a[k][j]; 24 c.a[i][j]%=mod; 25 // c.a[i][j]=c.a[i][j]%mod+x.a[i][k]*y.a[k][j]%mod; 26 } 27 } 28 } 29 return c; 30 } 31 matrix Quick_pow(matrix a,int k) 32 { 33 matrix ans; 34 ans.init(); 35 while(k) 36 { 37 if(k&1) ans=mul(ans,a); 38 a=mul(a,a); 39 k>>=1; 40 } 41 return ans; 42 } 43 44 45 int main() 46 { 47 matrix a; 48 a.a[0][0]=1,a.a[0][1]=1,a.a[1][0]=1,a.a[1][1]=0; 49 while(~scanf("%d",&n)&&n!=-1) 50 { 51 matrix ans=Quick_pow(a,n); 52 printf("%d ",ans.a[0][1]); 53 } 54 return 0; 55 }
b.板题的增强
斐波那契数列的前n项平方和:F[N]=F[N]*F[N+1]
牛客小白月赛20:
斐波那契数列前n项平方和
1 #include<cstdio> 2 #include<cstring> 3 const long long maxn=2;//阶数 4 const long long mod=1000000007; 5 struct matrix{ 6 long long a[2][2]; 7 void init()//结构体内的结构体成员数组的初始化函数 8 { 9 memset(a,0,sizeof(a)); 10 for(int i=0;i<maxn;++i) a[i][i]=1; 11 } 12 }; 13 14 matrix mul(matrix x,matrix y) 15 { 16 matrix c; 17 memset(c.a,0,sizeof(c.a));//结构体成员数组的清0 18 for(long long i=0;i<maxn;++i){//maxn为全局变量的阶数 19 for(long long j=0;j<maxn;++j){ 20 for(long long k=0;k<maxn;++k){ 21 // c.a[i][j]+=x.a[i][k]*y.a[k][j]; 22 // c.a[i][j]%=mod; 23 c.a[i][j]=(c.a[i][j]+x.a[i][k]*y.a[k][j])%mod;//更高效的运算大数求模 24 } 25 } 26 } 27 return c; 28 } 29 matrix Quick_pow(matrix a,long long k)//结构体函数返回结构体 30 { 31 matrix ans; 32 ans.init(); 33 while(k)//矩阵快速幂 34 { 35 if(k&1) ans=mul(ans,a); 36 a=mul(a,a); 37 k>>=1; 38 } 39 return ans; 40 } 41 42 43 int main() 44 { 45 long long n; 46 matrix a; 47 a.a[0][0]=1,a.a[0][1]=1,a.a[1][0]=1,a.a[1][1]=0; 48 scanf("%lld",&n); 49 matrix ans1=Quick_pow(a,n); 50 long long result1=ans1.a[0][1];//为什么取的是a[0][1]下面图片有讲解自行体会 51 matrix ans2=Quick_pow(a,n+1); 52 long long result2=ans2.a[0][1]; 53 printf("%lld ",result1*result2%mod);//乘积后可能再次大于模所以再一次求模 54 return 0; 55 }