Arc of Dream

题目传送-HDU4686

题意:

给定\(n\),\(a_0\),\(b_0\),\(ax\),\(ay\),\(bx\),\(by\)
定义:\(f(i)=a_n*b_n\)
\(a_n=a_{n-1}*ax+ay\)
\(b_n=b_{n-1}*bx+by\)
\(f(n)\)
\(n,a,b,ax,ay,bx,by \le 2^{18}\)
所有运算在\(mod 1e9+7\)意义下

题解:

显然的矩阵快速幂。
\(f\),\(a_nb_n\),\(a_n\),\(b_n\),\(a_x\),\(a_y\),\(b_x\),\(b_y\)构建转移关系即可

过程:

矩阵抄错,调了30min

代码:

const ll P=1e9+7;
const int LEN=10;
ll n;
ll ax,ay,a,bx,by,b;
struct MAT {
    ll mat[LEN][LEN];
    inline void print() {
        for(int i=0;i<=7;i++) {
            for(int j=0;j<=7;j++)
                printf("%lld ",mat[i][j]);
            puts("");
        }
    }
    inline void Construct() {
        mem(mat,0);
        mat[0][0]=1;
        mat[0][1]=1;
        mat[1][1]=ax*bx%P;
        mat[1][2]=ax*by%P;
        mat[1][3]=ay*bx%P;
        mat[1][5]=by;
        mat[2][2]=ax;
        mat[2][5]=1;
        mat[3][3]=bx;
        mat[3][7]=1;
        for(int i=4;i<=7;i++) mat[i][i]=1; 
    }
    inline void Init() {
        mat[0][0]=0;
        mat[1][0]=a*b%P;
        mat[2][0]=a;
        mat[3][0]=b;
        mat[4][0]=ax;
        mat[5][0]=ay;
        mat[6][0]=bx;
        mat[7][0]=by;
    }
    inline MAT operator * (const MAT &b)const {
        MAT c; mem(c.mat,0);
        for(int i=0;i<=7;i++)
            for(int j=0;j<=7;j++)
                for(int k=0;k<=7;k++) {
                    c.mat[i][j]+=mat[i][k]*b.mat[k][j]%P;
                    if(c.mat[i][j]>=P) c.mat[i][j]-=P;
                }
        return c;
    }
}trans,start,unit;
inline MAT Pow(MAT x,ll y) {MAT ret=unit; for(;y;y>>=1,x=x*x) if(y&1) ret=ret*x; return ret;} 
signed main() {
    for(int i=0;i<=7;i++) unit.mat[i][i]=1;
    while(scanf("%lld",&n)!=EOF) {
        read(a); read(ax); read(ay);
        read(b); read(bx); read(by);
        trans.Construct(); start.Init();
        trans=Pow(trans,n); //trans.print();
        printf("%lld\n",(trans*start).mat[0][0]);
    }
    return 0;
}
/*
1
1 2 3
4 5 6
2
1 2 3
4 5 6
3
1 2 3
4 5 6
*/

用时:1h

posted @ 2018-08-08 15:56  functionendless  阅读(130)  评论(0编辑  收藏  举报