传送门:www.lydsy.com:808/JudgeOnline/problem.php?id=3671
从hzwer神犇那看到的题解,第一眼:卧槽n^2m复杂度能过?测了测果然能过,第二眼:卧槽O(n^2+nm)的sb贪心啊,想好了就是noip难度的……
首先从小到大贪心,能走就走,然后问题就在于如何判断是否可行,蒟蒻考场上写了二维树状数组……60……其实记录一下每一列的可行区域就可以了……哇……哭瞎了
Code:
#include<bits/stdc++.h>
using namespace std;
const int maxn=5001;
int n,m,q;
long long x,a,b,c,d;
int getint(){
int res=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))(res*=10)+=ch-'0',ch=getchar();
return res;
}
int rnd(){
return x=(x*(a*x+b)+c)%d;
}
int t[maxn*maxn];
int pos[maxn*maxn];
int up[maxn],down[maxn];
int main(){
x=getint();a=getint();
b=getint();c=getint();
d=getint();n=getint();
m=getint();q=getint();
for(int i=1;i<=n*m;i++)t[i]=i;
for(int i=1;i<=n;i++)up[i]=m,down[i]=1;
for(int i=1;i<=n*m;i++)swap(t[i],t[(rnd()%i)+1]);
for(int i=1;i<=q;i++){
int u=getint(),v=getint();
swap(t[u],t[v]);
}
for(int i=1;i<=n*m;i++)pos[t[i]]=i;
int x,y,tot=0;
for(int i=1;i<=n*m;i++){
if(pos[i]%m)x=pos[i]/m+1;else x=pos[i]/m;
y=pos[i]%m?pos[i]%m:m;
if(y<=up[x]&&y>=down[x]){
for(int j=1;j<=n;j++)
if(j<x)up[j]=min(y,up[j]);
else if(j>x)down[j]=max(y,down[j]);
tot++;
printf("%d%c",i," \n"[tot==n+m-1]);\\drcow神犇的换行方式
if(tot==n+m-1)break;
}
}
return 0;
}