zoukankan      html  css  js  c++  java
  • CF385E Bear in the Field

    呜呜呜,调了我一下午的矩阵快速幂。(;′⌒`)

    Solution

    首先,我们将题目的意思模拟一下,可以得到:

    [dx_i=dx_{i-1}+sx_{i-1}+sy_{i-1}+i-1,\dy_i=dy_{i-1}+sx_{i-1}+sy_{i-1}+i-1,\sx_i=sx_{i-1}+dx_i,sy_i=sy_{i-1}+dy_i ]

    但是因为要 (\%n) ,所以坐标从 (1sim n) 到了 (0sim n-1) ,那么我们的速度此时会少2,因此再加上一个2。

    于是就有:

    [dx_i=dx_{i-1}+sx_{i-1}+sy_{i-1}+(i-1)+2\dy_i=dy_{i-1}+sx_{i-1}+sy_{i-1}+(i-1)+2\sx_i=sx_{i-1}+dx_i=2 imes sx_{i-1}+dx_{i-1}+sy_{i-1}+(i-1)+2,\sy_i=sy_{i-1}+dy_i=2 imes sy_{i-1}+dy_{i-1}+sx_{i-1}+(i-1)+2 ]

    下一步,我发现 (0le tle 10^{18}) ,于是想到了矩阵快速幂,发现的确 (sx,sy,dx,dy,i) 都和上一步有关系,那么转移矩阵就出来了:

    [egin{bmatrix}2~~~1~~~1~~~0~~~1~~~2\1~~~2~~~0~~~1~~~1~~~2\1~~~1~~~1~~~0~~~1~~~2\1~~~1~~~0~~~1~~~1~~~2\0~~~0~~~0~~~0~~~1~~~1\0~~~0~~~0~~~0~~~0~~~1end{bmatrix} ]

    初始矩阵也有:

    [egin{bmatrix}sx_0\sy_0\dx_0\dy_0\0\1end{bmatrix} ]

    然后就是:

    [egin{bmatrix}sx_n\sy_n\dx_n\dy_n\t\1end{bmatrix}=egin{bmatrix}2~~~1~~~1~~~0~~~1~~~2\1~~~2~~~0~~~1~~~1~~~2\1~~~1~~~1~~~0~~~1~~~2\1~~~1~~~0~~~1~~~1~~~2\0~~~0~~~0~~~0~~~1~~~1\0~~~0~~~0~~~0~~~0~~~1end{bmatrix}^tegin{bmatrix}sx\sy\dx\dy\0\1end{bmatrix} ]

    其实最后只需要 (sx_n,sy_n) ,所以转移完只需要单独算一下前两个就行了。

    代码

    #include<bits/stdc++.h>
    #define int long long
    
    using namespace std;
    const int N=15;
    int n,sx,sy,dx,dy,t,mod,y[N];
    
    inline int read(){
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
        return x*f;
    }
    
    inline int add(int a,int b){return a+b<mod?a+b:a+b-mod;}
    inline int sub(int a,int b){return a<b?a-b+mod:a-b;}
    inline int mul(int a,int b){return 1ll*a*b%mod;}
    
    inline fpow(int a,int b){
        int res=1;
        while(b){   
            if(b&1) res=mul(res,a);
            a=mul(a,a);
            b>>=1;
        }
        return res;
    }
    
    struct matrix{
        int a[N][N];
        matrix(){memset(a,0,sizeof(a));}
        matrix operator * (const matrix &x) const {
            matrix ans;
            for(int i=1;i<=6;i++)
                for(int j=1;j<=6;j++)
                    for(int k=1;k<=6;k++)
                        ans.a[i][j]=add(ans.a[i][j],mul(a[i][k],x.a[k][j]));
            return ans;
        }
    }I;
    
    matrix Fpow(matrix a,int b){
        matrix res;
        for(int i=1;i<=6;i++) res.a[i][i]=1;
        while(b){
            if(b&1) res=res*a;
            a=a*a;
            b>>=1;
        }
        return res;
    }
    
    inline void init(){
        y[1]=sx-1,y[2]=sy-1,y[3]=dx,y[4]=dy,y[5]=0,y[6]=1;
        I.a[1][1]=I.a[2][2]=I.a[1][6]=I.a[2][6]=I.a[3][6]=I.a[4][6]=2;
        I.a[1][2]=I.a[1][3]=I.a[1][5]=I.a[2][1]=I.a[2][4]=I.a[2][5]=I.a[3][1]=I.a[3][2]=I.a[3][3]=
        I.a[3][5]=I.a[4][1]=I.a[4][2]=I.a[4][4]=I.a[4][5]=I.a[5][5]=I.a[5][6]=I.a[6][6]=1;
    }
    
    signed main(){
        scanf("%lld%lld%lld%lld%lld%lld",&n,&sx,&sy,&dx,&dy,&t);
        if(t==0){
            printf("%lld %lld",sx,sy);
            return 0;
        }
        mod=n;
        init();
        I=Fpow(I,t);
        int ex=0,ey=0;
        for(int i=1;i<=6;i++)
            ex=((ex+I.a[1][i]*y[i])%mod+mod)%mod;
        for(int i=1;i<=6;i++)
            ey=((ey+I.a[2][i]*y[i])%mod+mod)%mod;
        printf("%lld %lld",ex+1,ey+1);
        return 0;
    }
    
  • 相关阅读:
    [转帖]VI使用手册
    hadoop安装配置
    永远的beyond!(4 days left to get back touch)
    求比较+围观(3 days left to get back touch)
    Windows及其他软件开发过程中一般都有哪些版本?
    程序员的7个坏习惯
    回来真好,,,
    Windows8 consumer preview的第一次
    那些年,备胎一起追的女神
    准备开始CP之旅。。。。(DP is Over!)
  • 原文地址:https://www.cnblogs.com/jasony/p/13733786.html
Copyright © 2011-2022 走看看