More than 2019 cattle off summer school camp (fifth) - B generator 1 (linear recursion + matrix fast power)

Topic link: https: //ac.nowcoder.com/acm/contest/885/B

The meaning of problems: Known homogeneous linear formula xn = a * xn-1 + b * xn-2, known to a, b, x0, x1, seeking xn, n large, n-<10 = 10. 6 ^ .

Idea: fast power matrix template title, structure matrix t:

a b
1 0

   Matrix ans:

x1 0
x0 0

   Obviously ans1 = t × ans, ans1 of:

x2 0
x1 0

   Then ansn = t ^ n * ans, ansn of:

xn + 1  0 
xn    0

   So fast computing power matrix t ^ n, n is large, rapid power use decimal multiplication, the calculation can not be directly every ride, but also with fast power Binary, or will TLE.

   Recently I write code like the evil of the same, according to other people's code to write a small place there is always wrong, and then look for the day wrong, consecutive days.

AC Code:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
 
typedef long long LL;
LL x0,x1,a,b;
int MOD;
char s[1000005];
 
struct Matrix{
    LL a[2][2];
    Matrix(){memset(a,0,sizeof(a));}
    Matrix operator * (const Matrix y){
        Matrix ret;
        for(int i=0;i<2;++i)
            for(int j=0;j<2;++j)
                for(int k=0;k<2;++k)
                    ret.a[i][j]=(ret.a[i][j]+a[i][k]*y.a[k][j])%MOD;
        return ret;
    }
    void operator = (const Matrix y){
        for(int i=0;i<2;++i)
            for(int j=0;j<2;++j)
                a[i][j]=y.a[i][j];
    }
}tmp;
 
Matrix qpow2(Matrix m,int b){
    Matrix ret=tmp;
    ret.a[0][0]=ret.a[1][1]=1;
    while(b){
        if(b&1) ret=ret*m;
        m=m*m;
        b>>=1;
    }
    return ret;
}
 
Matrix qpow10(Matrix m,char *s){
    Matrix ret=tmp;
    ret.a[0][0]=ret.a[1][1]=1;
    for(int i=strlen(s)-1;i>=0;--i){
        int num=s[i]-'0';
        ret=ret*qpow2(m,num);
        m=qpow2(m,10);
    }
    return ret;
}
 
int main(){
    scanf("%lld%lld%lld%lld",&x0,&x1,&a,&b);
    scanf("%s%d",s,&MOD);
    Matrix t,ans;
    t.a[0][0]=a,t.a[0][1]=b,t.a[1][0]=1,t.a[1][1]=0;
    ans.a [0] [0] = x1, ans.a [0] [1] = 0, ans.a [1] [0] = x0, ans.a [1] [1] = 1; 
    t = qpow10 (t, s); 
    years = t * years; 
    printf ( "% lld \ n", ans.a [1] [0]); 
    return 0; 
}

 

Guess you like

Origin www.cnblogs.com/FrankChen831X/p/11370331.html