贪心乱搞?
读完题感觉题面好神奇
然后现暴力求出格子排列
然后从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; }