矩阵快速幂

https://ac.nowcoder.com/acm/problem/19115

#include<bits/stdc++.h>
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pqueue priority_queue
#define NEW(a,b) memset(a,b,sizeof(a))
const double pi=4.0*atan(1.0);
const double e=exp(1.0);
const int maxn=1e6+8;
typedef long long LL;
typedef unsigned long long ULL;
const LL mod=10007;
using namespace std;
int dp[maxn];
int di[3];
struct maxt{
    int s[3][3];
    int ii,jj;
}t,x;
maxt MUL(maxt a,maxt b){
    int kk=a.jj;
    maxt ans;
    ans.ii=a.ii;
    ans.jj=b.jj;
    for(int i=1;i<=a.ii;i++){
        for(int j=1;j<=b.jj;j++){
            ans.s[i][j]=0;
            for(int k=1;k<=kk;k++){
                ans.s[i][j]+=a.s[i][k]*b.s[k][j];
            }
            ans.s[i][j]%=mod;
        }
    }
    return ans;
}
maxt mqpow(maxt x,LL u){
    maxt ans;
    ans.ii=x.ii;
    ans.jj=x.jj;
    for(int i=1;i<=ans.ii;i++){
        for(int j=1;j<=ans.jj;j++){
            if(i==j){
                ans.s[i][j]=1;
            }
            else{
                ans.s[i][j]=0;
            }
        }
    }
    while(u){
        if(u&1){
            ans=MUL(ans,x);
        }
        x=MUL(x,x);
        u>>=1;
    }
    return ans;
}
LL qpow(LL a,LL b){
    LL ans=1;
    while(b){
        if(b&1){
            ans=ans*a%mod;
        }
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}
int main(){
    int n,k;
    cin>>n>>k;
    dp[1]=k;
    di[1]=0;
    di[0]=k;
    t.ii=t.jj=2;
    t.s[1][1]=k-2;
    t.s[1][2]=k-1;
    t.s[2][1]=1;
    t.s[2][2]=0;
    x.s[2][1]=0;
    x.s[1][1]=k*(k-1)%mod;
    x.ii=2;
    x.jj=1;
    maxt g=mqpow(t,n-2);
    g=MUL(g,x);
    int dii=g.s[2][1];
    int dpp=dp[1]*qpow(k-1,n-1)%mod;
    int ans=dpp-dii;
    ans%=mod;
    if(ans<0) ans+=mod;
    cout<<ans<<endl;
}

 

posted @ 2019-02-24 16:59  我要见血小板  阅读(157)  评论(0编辑  收藏  举报