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\) ,所以坐标从 \(1\sim n\) 到了 \(0\sim 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\times sx_{i-1}+dx_{i-1}+sy_{i-1}+(i-1)+2,\\sy_i=sy_{i-1}+dy_i=2\times sy_{i-1}+dy_{i-1}+sx_{i-1}+(i-1)+2 \]

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

\[\begin{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~~~1\end{bmatrix} \]

初始矩阵也有:

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

然后就是:

\[\begin{bmatrix}sx_n\\sy_n\\dx_n\\dy_n\\t\\1\end{bmatrix}=\begin{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~~~1\end{bmatrix}^t\begin{bmatrix}sx\\sy\\dx\\dy\\0\\1\end{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;
}
posted @ 2020-09-26 09:17  jasony_sam  阅读(106)  评论(0编辑  收藏  举报