为什么NOI2014有模拟题=。=???
按题意把序列生成出来之后,对每一行维护一个能取到的最左侧和能取到的最右侧。从小到大$O(n^2)$枚举数字看看能否填入,能填入则暴力$O(n)$更新信息,因为能填入的总共只有$n+m$级别个数的数,所以复杂度没问题
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N=5005,inf=1e9; 6 int d,n,m,q,nm,t1,t2,s[4]; 7 int x[N*N],p[N*N],ll[N],rr[N]; 8 void Add(int &x,int y) 9 { 10 x+=y; 11 if(x>=d) x-=d; 12 } 13 bool Able(int o) 14 { 15 int x=(o-1)/m+1,y=o%m; if(!y) y=m; 16 if(y>=ll[x]&&y<=rr[x]) 17 { 18 for(int i=1;i<x;i++) rr[i]=min(rr[i],y); 19 for(int i=x+1;i<=n;i++) ll[i]=max(ll[i],y); 20 return true; 21 } 22 return false; 23 } 24 int main() 25 { 26 scanf("%d%d%d%d%d",&x[0],&s[1],&s[2],&s[3],&d); 27 scanf("%d%d%d",&n,&m,&q),nm=n*m; 28 for(int i=1;i<=nm;p[i]=i,i++) 29 for(int j=3,t=1;j;t=1ll*t*x[i-1]%d,j--) 30 Add(x[i],1ll*t*s[j]%d); 31 for(int i=1;i<=nm;i++) swap(p[i],p[x[i]%i+1]); 32 for(int i=1;i<=q;i++) 33 scanf("%d%d",&t1,&t2),swap(p[t1],p[t2]); 34 for(int i=1;i<=n*m;i++) x[p[i]]=i; 35 for(int i=1;i<=n;i++) ll[i]=1,rr[i]=m; 36 for(int i=1;i<=nm;i++) 37 if(Able(x[i])) printf("%d ",i); 38 return 0; 39 }