快速幂+乘模 模板
/************** 快速幂模板 调用:Quk_Mul(a,b,mod) 返回:a^b%mod 复杂度:当mod>10^9,log(mod)*log(b),否则log(b) ***************/ long long Mod_Mul(long long a,long long b,long long mod) { long long msum=0; while(b) { if(b&1) msum = (msum+a)%mod; b>>=1; a = (a+a)%mod; } return msum; } long long Quk_Mul(long long a,long long b,long long mod) { bool qmflag=mod>2e9?1:0; long long qsum=1; while(b) { if(b&1) qsum = (qmflag==1) ? Mod_Mul(qsum,a,mod) : (qsum*a)%mod; b>>=1; a = (qmflag==1) ? Mod_Mul(a,a,mod) : (a*a)%mod; } return qsum; }
/*****-矩阵快速幂模板-*****/ //复杂度O(N^3) //构造好xx,然后返回rt = xx^n #define MN 2 void calmul(long long s[MN][MN],long long t[MN][MN]) { long long tmp[MN][MN]; memset(tmp,0,sizeof(tmp)); for(int k=0;k<MN;k++) for(int i=0;i<MN;i++) for(int j=0;j<MN;j++) { tmp[i][j]=(tmp[i][j]+s[i][k]*t[k][j])%MOD; } for(int i=0;i<MN;i++) for(int j=0;j<MN;j++) s[i][j]=tmp[i][j]; } void Quk_Mul(long long rt[MN][MN],long long xx[MN][MN],long long _n) { long long _tmp[MN][MN],_sum[MN][MN];//为了不改变传入的xx for(int i=0;i<MN;i++) for(int j=0;j<MN;j++) _tmp[i][j] = xx[i][j],_sum[i][j]=0; for(int i=0;i<MN;i++) _sum[i][i] = 1; while(_n) { if(_n&1) calmul(_sum,_tmp); _n >>= 1; calmul(_tmp,_tmp); } for(int i=0;i<MN;i++) for(int j=0;j<MN;j++) rt[i][j] = _sum[i][j]; }