呜呜呜,调了我一下午的矩阵快速幂。(;′⌒`)
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;
}