矩阵快速幂模板

(1,1   的n-2次方 * (1,0   得到 (   f[n-1]    上面 × a2  得到的和就是  f[n]

 1,0)                       0,1)             f[n-2] )          *  a1

#include<bits/stdc++.h>
#define rep(i,x,y) for(register int i=x;i<=y;i++)
#define ll long long
using namespace std;
inline ll read(){
    ll x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;}
ll n,m,p,a1,a2;
struct matrix{ll g[2][2];};
ll qpow(ll a,ll n){
    ll s=1;
    while(n){
        if(n&1) s=(s*a)%p;//注意乘法顺序
        a=(a*a)%p;n>>=1;}
    return s;}
matrix mul(matrix a,matrix b){
    matrix c;
    c.g[0][0]=c.g[0][1]=c.g[1][0]=c.g[1][1]=0;
    rep(i,0,1)rep(j,0,1)rep(k,0,1)
    c.g[i][j]=(c.g[i][j]+a.g[i][k]*b.g[k][j])%p;
    return c;}
matrix qqpow(matrix a,ll n){
    matrix s;
    s.g[0][0]=s.g[1][1]=1;
    s.g[0][1]=s.g[1][0]=0;
    while(n){
        if(n&1) s=mul(s,a);
        a=mul(a,a);n>>=1;}
    return s;}
char ch;
matrix ans;
int main(){
    freopen("math.in","r",stdin);
    freopen("math.out","w",stdout);
    cin>>ch;
    if(ch=='A'){
        n=read(),m=read(),p=read();
        printf("%lld\n",qpow(n,m));}
    else{
        matrix a;
        a.g[0][0]=a.g[0][1]=a.g[1][0]=1;
        a.g[1][1]=0;
        a1=read(),a2=read(),n=read(),p=read();
        ans=qqpow(a,n-2);
        printf("%lld\n",(a2*ans.g[0][0]+a1*ans.g[1][0])%p);}
    return 0;
} 

或者直接将第一二项修改即可

#include<bits/stdc++.h>
#define rep(i,x,y) for(register int i=x;i<=y;i++)
#define ll long long
using namespace std;
inline ll read(){
    ll x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;}
ll n,m,p,a1,a2;
struct matrix{ll g[2][2];};
ll qpow(ll a,ll n){
    ll s=1;
    while(n){
        if(n&1) s=(s*a)%p;
        a=(a*a)%p;n>>=1;}
    return s;}
matrix mul(matrix a,matrix b){
    matrix c;
    c.g[0][0]=c.g[0][1]=c.g[1][0]=c.g[1][1]=0;
    rep(i,0,1)rep(j,0,1)rep(k,0,1)
    c.g[i][j]=(c.g[i][j]+a.g[i][k]*b.g[k][j])%p;
    return c;}
matrix qqpow(matrix a,ll n){
    matrix s;
    s.g[0][0]=s.g[1][1]=a2; 
    s.g[0][1]=s.g[1][0]=a1;
    while(n){
        if(n&1) s=mul(s,a);
        a=mul(a,a);n>>=1;}
    return s;}
char ch;
matrix ans;
int main(){
    freopen("math.in","r",stdin);
    freopen("math.out","w",stdout);
    cin>>ch;
    if(ch=='A'){
        n=read(),m=read(),p=read();
        printf("%lld\n",qpow(n,m));}
    else{
        matrix a;
        a.g[0][0]=a.g[0][1]=a.g[1][0]=1;
        a.g[1][1]=0;
        a1=read(),a2=read(),n=read(),p=read();
        ans=qqpow(a,n-2);
        printf("%lld\n",ans.g[0][0]%p);}
    return 0;
} 

 

posted @ 2018-09-09 18:23  ASDIC减除  阅读(112)  评论(0编辑  收藏  举报