快速冪+矩陣快速冪模板
阿新 • • 發佈:2018-10-31
#include<iostream> #include<cstring> #include<cmath> #include<cstdlib> #include<cstdio> #include<algorithm> #include<string> #include<map> #include<queue> #include<vector> #include<stack> #define ll long long #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; const int N=110; const int p=1e9+7; ll tmp[N][N],f[N],a[N][N],res[N][N]; int n,m,k; ll quick_mod(ll a,ll b) { ll ans=1; a%=p; while(b) { if(b&1) {ans=ans*a%p;b--;} b>>=1;a=a*a%p; } return ans; }//快速冪 void multi(ll a[][N],ll b[][N],int n) { memset(tmp,0,sizeof tmp); for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++) tmp[i][j]=(tmp[i][j]+a[i][k]*b[k][j])%p; for(int i=0;i<n;i++) for(int j=0;j<n;j++) a[i][j]=tmp[i][j]; } void Pow(ll a[][N],int x) { memset(res,0,sizeof res);//n???N????? for(int i=0;i<N;i++) res[i][i]=1; while(x) { if(x&1) multi(res,a,k-1); multi(a,a,k-1); x>>=1; } } //矩陣快速冪 int main() { while(scanf("%d%d%d",&n,&m,&k)!=EOF) { ll ans=0; if(k==1) { printf("%lld\n",quick_mod(m,n)); continue; } memset(a,0,sizeof(a));//?? for(int i=0;i<k;i++) a[0][i]=m-1; for(int i=1;i<k;i++) a[i][i-1]=1; memset(f,0,sizeof(f)); f[1]=m; for(int i=2;i<=k;i++) for(int j=1;j<k;j++) { if(i-j==0) { f[i]=(f[i]+m)%p; continue; } f[i]=(f[i]+f[i-j]*(m-1))%p; } if(n<=k) { ll ans=quick_mod(m,n)-f[n]; ans=(ans+p)%p; printf("%lld\n",ans); continue; } Pow(a,n-k+1); for(int i=0;i<k-1;i++) ans=(ans+f[k-i-1]*res[0][i])%p; ans=(quick_mod(m,n)-ans)%p; ans=(ans+p)%p; printf("%lld\n",ans); } }