NOI2014 随机数生成器
题目链接:戳我
从小到大贪心.
注意到放入一个数之后,它往上的行就不能放这个y坐标之后的数了,往下的行不能放这个y坐标之前的数qwq
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 5001
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
int n,m,a,b,c,d,q,cnt;
int f[MAXN*MAXN],p[MAXN*MAXN],L[MAXN],R[MAXN];
bool ex[MAXN*MAXN];
inline int id(int x,int y){return x*(m-1)+y;}
inline int get_x(int x)
{
int cur_ans=x/m;
if(x%m!=0) cur_ans++;
return cur_ans;
}
inline int get_y(int x)
{
int cur_ans=get_x(x);
return x-(cur_ans-1)*m;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
p[0]=read(),a=read(),b=read(),c=read(),d=read();
n=read(),m=read(),q=read();
for(int i=1;i<=n*m;i++)
{
p[i]=(p[i]+1ll*a*p[i-1]%d*p[i-1]%d)%d;
p[i]=(p[i]+1ll*b*p[i-1]%d)%d;
p[i]=(p[i]+c)%d;
}
// for(int i=1;i<=n*m;i++) printf("%d ",p[i]); puts("");
for(int i=1;i<=n*m;i++) f[i]=i;
for(int i=1;i<=n*m;i++)
{
int x=i,y=p[x]%i+1;
swap(f[x],f[y]);
}
// for(int i=1;i<=n*m;i++) printf("%d ",f[i]); puts("");
while(q--)
{
int x=read(),y=read();
swap(f[x],f[y]);
}
// for(int i=1;i<=n*m;i++)printf("%d ",f[i]); puts("");
for(int i=1;i<=n*m;i++) p[f[i]]=i;
for(int i=1;i<=n;i++) L[i]=1,R[i]=m;
for(int i=1;i<=n*m;i++)
{
int x=get_x(p[i]),y=get_y(p[i]);
if(L[x]<=y&&y<=R[x])
{
printf("%d ",i);
cnt++;
if(cnt==n+m-1) break;
for(int j=1;j<x;j++) R[j]=min(R[j],y);
for(int j=x+1;j<=n;j++) L[j]=max(L[j],y);
}
}
return 0;
}