Description
Time Limits: 4000 ms Memory Limits: 524288 KB
Input
Output
Sample Input
4 4
1 2 9 3
3 5 4 8
4 3 2 7
5 8 1 6
4
move 1
move 1
change 1 4 100
move 1
Sample Output
4 2
1 3
1 4
Data Constraint
思路
考虑没有change操作时怎么做。
对于每个位置我们都可以预处理出它跳M步后的位置。(使得棋子再度回到当前列)
在每一次move操作时,
我们直接M步M步的跳,
若其在当前列的某个位置出现两次时,则明显形成了个循环。
我们让K值对这个循环长度取模。
然后再M步M步的跳,最后再一步一步。
最坏情况复杂度是O(N+M)的,可以过。
考虑加入change操作。
一次change可能会对N*M个状态都产生影响,若同时维护每个地方跳M步后的位置,绝对会TLE。
考虑只维护一列(第一列)的状态(跳(M-1)步后落在最后一列的哪一行)。
(使得每次change更改的状态数在合理的复杂度内,均摊复杂度)
对于change一个位置的值,只对该位置前3个点的指向方向造成影响,
如果此时暴力去找有哪些第一列的点经过了该位置,又会TLE。
所以我们对于每个位置,还得维护一个值表示第一列有那些位置的点跳(M-1)步会经过它。
不难发现第一列的这些位置一定是一段连续的区间,所以我们设L,R两个数组表示它。
不过有些情况下L会大于R,即此区间是[1,R]并[L,N]
,这得特殊考虑一下。
L,R数组的维护,得从更改位置向后走到最后一列,
前3个点的新指向也得这样操作一次,每次走都更新一遍L,R值。
维护了L,R值,对于第一列的状态就暴力从前3个点走到最后一列更新维护其状态。
代码
打得有点丑,见谅。
这样实现细节贼恶心。
#pragma GCC optimize(3,"Ofast","inline")
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=2005;
int f[10][5]={{1,1},{0,1},{-1,1}};
int e[10][5]={{-1,-1},{0,-1},{1,-1}};
int N,M,Q,X,Y,vis[MAXN];
int a[MAXN][MAXN];
int pt[MAXN][MAXN];
int dp[MAXN][MAXN];
int L[MAXN][MAXN];
int R[MAXN][MAXN];
int vvis[10];
vector<int>P;char c[5];
queue<int>T1,T2;
inline void read(int &x){
x=0;char c=getchar();bool f=0;
if(c=='-')f=1;
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
if(f==1)x=-x;
}
int Add(int x,int y,int z){
if(x+y>=z)return x+y-z;
if(x+y<0)return x+y+z;
return x+y;
}
int dfs(int x,int y){
if(y==M-1)return dp[x][y]=x;
int w1=(x+f[pt[x][y]][0]+N)%N;
int w2=(y+f[pt[x][y]][1]+M)%M;
return dp[x][y]=dfs(w1,w2);
}
inline void Init(int x,int y){
L[x][y]=R[x][y]=-1;
for(int i=0;i<3;i++){
int w1=Add(x,e[i][0],N);
int w2=Add(y,e[i][1],M);
int ww1=Add(w1,f[pt[w1][w2]][0],N);
int ww2=Add(w2,f[pt[w1][w2]][1],M);
if(ww1==x&&ww2==y){
if(L[w1][w2]==-1)continue;
if(L[x][y]==-1){
L[x][y]=L[w1][w2];
R[x][y]=R[w1][w2];
continue;
}
if(L[x][y]==Add(R[w1][w2],1,N))
L[x][y]=L[w1][w2];
else if(Add(R[x][y],1,N)==L[w1][w2])
R[x][y]=R[w1][w2];
}
}
}
inline void Turn(int A,int B){
if(B==M-1)return ;
for(int i=0;i<3;i++){
int x=Add(A,f[i][0],N);
int y=Add(B,f[i][1],M);
Init(x,y);
}
}
inline void bfs(){
while(!T1.empty()){
int A=T1.front();T1.pop();
int B=T2.front();T2.pop();
int x=Add(A,f[pt[A][B]][0],N);
int y=Add(B,f[pt[A][B]][1],M);
Init(x,y);
if(y!=M-1)T1.push(x),T2.push(y);
}
}
int main(){
//freopen("read.in","r",stdin);
//freopen("output.out","w",stdout);
freopen("jump.in","r",stdin);
freopen("jump.out","w",stdout);
read(N);read(M);
for(int i=0;i<N;i++)
for(int j=0;j<M;j++)
read(a[i][j]);
for(int i=0;i<N;i++)
for(int j=0;j<M;j++){
int rt=-1;
for(int k=0;k<3;k++){
int w1=Add(i,f[k][0],N);
int w2=Add(j,f[k][1],M);
if(rt<a[w1][w2]){
rt=a[w1][w2];
pt[i][j]=k;
}
}
}
memset(L,-1,sizeof(L));
memset(R,-1,sizeof(R));
memset(dp,-1,sizeof(dp));
for(int i=0;i<N;i++){
L[i][0]=R[i][0]=i;
dp[i][0]=dfs(i,0);
}
for(int y=1;y<M;y++)
for(int x=0;x<N;x++)
Init(x,y);
read(Q);
while(Q--){//O(N*Q)
scanf("%s",c+1);
if(c[1]=='m'){
int k;read(k);
while(k&&Y!=0){
int x=Add(X,f[pt[X][Y]][0],N);
int y=Add(Y,f[pt[X][Y]][1],M);
X=x;Y=y;k--;
}
if(!k){
printf("%d %d\n",X+1,Y+1);
continue;
}
memset(vis,0,sizeof(vis));
int tot=M,Cnt=0;
while(k>=M){
if(vis[X]){tot=((++Cnt)-vis[X])*M;break;}vis[X]=++Cnt;
k-=M,X=Add(dp[X][0],f[pt[dp[X][0]][M-1]][0],N);
}
k%=tot;
while(k>=M)
k-=M,X=Add(dp[X][0],f[pt[dp[X][0]][M-1]][0],N);
while(k){
int x=Add(X,f[pt[X][Y]][0],N);
int y=Add(Y,f[pt[X][Y]][1],M);
X=x;Y=y;k--;
}
printf("%d %d\n",X+1,Y+1);
}
if(c[1]=='c'){
int A,B,V,tp[5]={0};
read(A);read(B);read(V);
A--;B--;a[A][B]=V;
for(int i=0;i<3;i++){
int x=Add(A,e[i][0],N);
int y=Add(B,e[i][1],M);
int rt=-1;tp[i]=pt[x][y];
for(int j=0;j<3;j++){
int w1=Add(x,f[j][0],N);
int w2=Add(y,f[j][1],M);
if(rt<a[w1][w2]){
rt=a[w1][w2];
pt[x][y]=j;
}
}
}
for(int i=0;i<3;i++){
int x=Add(A,e[i][0],N);
int y=Add(B,e[i][1],M);
if(L[x][y]!=-1){
dp[x][y]=dfs(x,y);
if(R[x][y]<L[x][y]){
for(int j=0;j<=R[x][y];j++)
dp[j][0]=dp[x][y];
for(int j=L[x][y];j<N;j++)
dp[j][0]=dp[x][y];
}
else for(int j=L[x][y];j<=R[x][y];j++)
dp[j][0]=dp[x][y];
}
}
if(B!=0){
while(!T1.empty())T1.pop();
while(!T2.empty())T2.pop();
memset(vvis,0,sizeof(vvis));
for(int i=0;i<3;i++){
int x=Add(A,e[i][0],N);
int y=Add(B,e[i][1],M);
if(tp[i]==pt[x][y])continue;
Turn(x,y);
if(B!=M-1){
if(!vvis[e[i][0]+f[tp[i]][0]+2]){
vvis[e[i][0]+f[tp[i]][0]+2]=1;
T1.push(Add(x,f[tp[i]][0],N));
T2.push(Add(y,f[tp[i]][1],M));
}
if(!vvis[e[i][0]+f[pt[x][y]][0]+2]){
vvis[e[i][0]+f[pt[x][y]][0]+2]=1;
T1.push(Add(x,f[pt[x][y]][0],N));
T2.push(Add(y,f[pt[x][y]][1],M));
}
}
}
bfs();
}
}
}
}
/*
5 5
0 3 1 1 1
1 7 3 3 3
2 9 10 10 10
3 7 5 5 5
4 2 2 2 2
10000
change 3 3 0
change 3 5 0
move 4
*/