快速幂+矩阵快速幂模板

#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);
	}
} 

 

posted @ 2018-10-01 10:04  The-Pines-of-Star  阅读(97)  评论(0编辑  收藏  举报