快速幂取模(位运算加速)
LL fastpow(LL a,LL b) { a%=mod; LL ans=1; while(b>0) { if(b&1)ans=(ans*a)%mod; a=(a*a)%mod; b>>=1; } return ans; }
快速乘法取模
LL fastmulti(LL a,LL b) { LL ans=0; while(b>0) { if(b&1)ans=(ans+a)%mod; a=(a+a)%mod; b>>=1; } return ans; }
快速乘法+快速幂(当所给数非常大的时候用)
LL fastmulti(LL a,LL b) { LL ans=0; while(b>0) { if(b&1)ans=(ans+a)%mod; a=(a+a)%mod; b>>=1; } return ans; } LL multipow(LL a,LL b) { LL ans=1; a%=mod; while(b>0) { if(b&1)ans=fastmulti(ans,a); a=fastmulti(a,a); b>>=1; } return ans; }
矩阵快速幂
难处在于求解递推式
struct mat { LL a[3][3]; }; mat matmul(mat x,mat y)//矩阵乘法 { mat res; memset(res.a,0,sizeof res.a); int i,j,k; for(i=0;i<3;i++) { for(j=0;j<3;j++) { for(k=0;k<3;k++) { res.a[i][j]+=x.a[i][k]*y.a[k][j]%mod; res.a[i][j]%=mod; } } } return res; } mat matpow(mat x,LL n)//矩阵快速幂 { mat res; memset(res.a,0,sizeof res.a); for(int i=0;i<3;i++)res.a[i][i]=1;//构造一个单位矩阵E,相当于快速幂里的LL ans=1; while(n>0) { if(n&1)res=matmul(res,x); x=matmul(x,x); n>>=1; } return res; }