1.A sequence of numbers
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3670
题解:这是一道隐藏的快速幂的模板题,从数据我们就可以知道。对该题进行分析,如何判别是等差or等比,通过比较a[2]-a[1]==a[3]-a[2]如果相等,则为等差
否则a[2]/a[1]==a[3]/a[2],就为等比,然后利用快速幂来解决等比。
代码:
#includeusing namespace std; typedef long long ll; const int mod=200907; ll N,K; ll a[10]; ll fastPow(ll a,ll n) { ll res=1; while(n) { if(n&1) res=(res*a)%mod; a=(a*a)%mod; n>>=1; } return res; } int main() { ll i,j; cin>>N; while(N--) { for(i=1;i<=3;i++) cin>>a[i]; cin>>K; if(a[2]-a[1]==a[3]-a[2]) { cout<<(a[1]+((a[2]-a[1])%mod)*((K-1)%mod))%mod<<endl; } else if(a[2]/a[1]==a[3]/a[2]) { ll q=a[2]/a[1]; ll c=K-1; cout<<(fastPow(q,c)*a[1])%mod<<endl; } } return 0; }
2.Rightmost Digit
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1061
题解:这是一道典型的快速幂,只不过有一点需要注意,不要再完成运算后再取模,应该边运算边取模,否则会TLE
代码:
#includeusing namespace std; typedef long long ll; ll T; ll fastPow(ll a,ll n) { ll res=1; while(n) { if(n&1) res=(res*a)%10; a=(a*a)%10; n>>=1; } res=res%10; return res; } int main() { ll i,j,N; cin>>T; while(T--) { cin>>N; ll ans=fastPow(N,N); cout< endl; } return 0; }
3.矩阵快速幂
题目:https://www.luogu.com.cn/problem/P3390
题解:一道入门级矩阵快速幂的运算
代码:
#include#include using namespace std; const int MAXN=110; const int MOD=1e9+7; typedef long long ll; struct Matrix{ ll m[MAXN][MAXN]; Matrix() { memset(m,0,sizeof(m)); } }; Matrix Multi(Matrix a,Matrix b) { Matrix res; for(ll i=0;i ) { for(ll j=0;j ) { for(ll k=0;k ) res.m[i][j]=(res.m[i][j]+a.m[i][k]*b.m[k][j])%MOD; } } return res; } Matrix fastm(Matrix a,ll n) { Matrix res; for(ll i=0;i ) res.m[i][i]=1; while(n) { if(n&1) res=Multi(res,a); a=Multi(a,a); n>>=1; } return res; } int main() { ll n,k,i,j; Matrix s; cin>>n>>k; for(i=0;i ) { for(j=0;j ) cin>>s.m[i][j]; } s=fastm(s,k); for(i=0;i ) { for(j=0;j ) cout< " "; cout<<endl; } return 0; }
4.矩阵加速
题目:https://www.luogu.com.cn/problem/P1939
题解:一道需要求出对应矩阵的矩阵快速幂的运算。
分析一下:
a[n]=1*a[n-1]+0*a[n-2]+1*a[n-3]
a[n-1]=1*a[n-1]+0*a[n-2]+0*a[n-3]
a[n-2]=0*a[n-1]+1*a[n-2]+0*a[n-3]
因此,我们可以总结出:
进而,对其进行推到,因为我们已知a1=a2=a3=1,所以尽可能使右边的行列式替换成已知数,因此,最终的公式为:
这样我们最终要求的就是an在数组中的位置为res.m[0][0],然后我们利用矩阵快速幂来求解行列式的n-3次方的值乘以行列式即可
其中,需要注意的是MAXN=3还有对于小于等于3的进行特判,否则会TLE的
代码:
#include#include using namespace std; typedef long long ll; const int MAXN=3; const long long MOD=1e9+7; struct Matrix { ll m[MAXN][MAXN]; Matrix() { memset(m,0,sizeof(m)); } }; Matrix Multi(Matrix a,Matrix b) { Matrix res; for(ll i=0;i ) { for(ll j=0;j ) { for(ll k=0;k ) res.m[i][j]=(res.m[i][j]+a.m[i][k]%MOD*b.m[k][j]%MOD)%MOD; res.m[i][j]%=MOD; } } return res; } Matrix fastm(Matrix a,ll n) { Matrix res; for(ll i=0;i ) res.m[i][i]=1; while(n) { if(n&1) res=Multi(res,a); a=Multi(a,a); n>>=1; } return res; } int main() { ll i,j,t,n; cin>>t; while(t--) { cin>>n; if(n <= 3) { printf("1\n"); continue; } Matrix k,s,res; k.m[0][0]=1; k.m[1][0]=1; k.m[2][0]=1; s.m[0][0]=1;s.m[0][1]=0;s.m[0][2]=1; s.m[1][0]=1;s.m[1][1]=0;s.m[1][2]=0; s.m[2][0]=0;s.m[2][1]=1;s.m[2][2]=0; s=fastm(s,n-3); res=Multi(s,k); cout< 0][0]<<endl; } return 0; }