hdu 4686 Arc of Dream_矩阵快速幂

题意:略

构造出矩阵就行了

                                                                      |   AX   0    AXBY   AXBY       0  |
                                                                      |   0     BX    AYBX    AYBX    0  |
{a[i-1]   b[i-1]   a[i-1]*b[i-1]  AoD[i-1]  1}*        |   0     0      AXBX      AXBX   0  |  = {a[i]   b[i]   a[i]*b[i]  AoD[i]  1}
                                                                      |   0    0     0           1              0    |
                                                                      |  AY    BY   AYBY   AYBY     1   |

#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define LL __int64
#define N 5
#define m 1000000007 
struct node{
    LL mat[N][N];
    node operator *(const node &x){
            node tmp;
            memset(tmp.mat,0,sizeof(tmp.mat));
            for(int i=0;i<N;i++)
            for(int k=0;k<N;k++)
            if(mat[i][k])
                for(int j=0;j<N;j++){
                    tmp.mat[i][j]+=(mat[i][k]*x.mat[k][j])%m;
                    tmp.mat[i][j]%=m;
                }
            return tmp;
    }
}cat,b;
void _pow(LL n){
    while(n){
        if(n&1)        
            b=b*cat;
        cat=cat*cat;
        n>>=1;
    }
    //return b;
}
int main(int argc, char** argv) {
    LL a0,ax,ay,b0,bx,by;
    LL n;
    while(scanf("%I64d",&n)!=EOF){
        scanf("%I64d%I64d%I64d",&a0,&ax,&ay);
        scanf("%I64d%I64d%I64d",&b0,&bx,&by);
        //printf("!%I64d %I64d %I64d\n",a0,ax,ay);
        //printf("!%I64d %I64d %I64d\n",b0,bx,by);
        memset(cat.mat,0,sizeof(cat.mat));
        cat.mat[3][0]=cat.mat[4][4]=cat.mat[0][0]=1;
        cat.mat[1][1]=ax;
        cat.mat[4][1]=ay;
        cat.mat[2][2]=bx;
        cat.mat[4][2]=by;
        cat.mat[1][3]=ax*by%m;
        cat.mat[2][3]=ay*bx%m;
        cat.mat[3][3]=ax*bx%m;
        cat.mat[4][3]=ay*by%m;
        b.mat[0][0]=0;
        b.mat[0][1]=a0;
        b.mat[0][2]=b0;
        b.mat[0][3]=a0*b0%m;
        b.mat[0][4]=1;
        _pow(n);
        printf("%I64d\n",b.mat[0][0]);
        
    }
    
    
    return 0;
}


posted @ 2013-11-13 22:25  Teemo的技术blog  阅读(91)  评论(0编辑  收藏  举报