zoukankan      html  css  js  c++  java
  • 快速幂+矩阵快速幂模板

    #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
    ",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
    ",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
    ",ans);
    	}
    } 
  • 相关阅读:
    Corn Fields 状压动归入门题
    codevs 2800 送外卖 floyd + Tsp
    互不侵犯 状压动归入门题
    跨终端电商平台的实现之手势效果(左右滑动)
    nodejs和树莓派开发以及点亮RGB的LED灯代码
    基于vue-cli搭了一个多页面应用的空脚手架
    About HTML
    【译】遗留浏览器中的表单
    Vue2的右键弹出菜单(vue-contextmenu)
    IMWEB 前端面试题汇总
  • 原文地址:https://www.cnblogs.com/The-Pines-of-Star/p/9878816.html
Copyright © 2011-2022 走看看