贪心乱搞?
读完题感觉题面好神奇
然后现暴力求出格子排列
然后从1开始枚举看能否加入,若可以把其左下右上所有点标记(用bool否则超空间)
每个点至多被记一次,所以复杂度为O(n*m),常数好像较大
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<string>
#include<map>
using namespace std;
bool st;
int x0,a,b,c,d;
int n,m,q,op;
int cnt=0;
int ui[50005],vi[50005];
int kp[5002][5002];
bool acad[5002][5005];
int chao[25000005];
bool sd;
void change(int sign1,int sign2)
{
int sx1,sx2,sy1,sy2,k;
sx1=sign1/m;
if(sign1%m==0)sy1=m;
else {sx1++;sy1=sign1%m;}
sx2=sign2/m;
if(sign2%m==0)sy2=m;
else {sx2++;sy2=sign2%m;}
k=kp[sx1][sy1];
kp[sx1][sy1]=kp[sx2][sy2];
kp[sx2][sy2]=k;
}
void lcr(int l,int r)
{
int i,j;
l++;r--;
for(i=l;i<=n;i++){
if(!acad[i][r])break;
for(j=r;j>=1;j--){
if(acad[i][j])acad[i][j]=false;
else break;
}
}
l-=2;r+=2;
for(i=l;i>=1;i--){
if(!acad[i][r])break;
for(j=r;j<=m;j++){
if(acad[i][j])acad[i][j]=false;
else break;
}
}
}
int main()
{
freopen("random.in","r",stdin);
freopen("random.out","w",stdout);
int i,j,k,sx,sy;
scanf("%d%d%d%d%d",&x0,&a,&b,&c,&d);
scanf("%d%d%d",&n,&m,&q);
for(i=1;i<=q;i++)scanf("%d%d",&ui[i],&vi[i]);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++){
kp[i][j]=(i-1)*m+j;
acad[i][j]=true;
}
for(i=1;i<=n*m;i++){
x0=((long long)a*x0*x0+(long long)b*x0+c)%d;
change(x0%i+1,i);
}
for(i=1;i<=q;i++)
change(ui[i],vi[i]);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
chao[kp[i][j]]=(i-1)*m+j;
for(i=1;i<=n*m;i++){
sx=chao[i]/m;
if(chao[i]%m==0)sy=m;
else {sx++;sy=chao[i]%m;}
if(acad[sx][sy]){
lcr(sx,sy);
cnt++;
printf("%d ",i);
}
if(cnt==(n+m-1))break;
}
return 0;
}