BZOJ 3671 [NOI2014 D2T2] 随机数生成器

来源:互联网 发布:福耀玻璃 知乎 编辑:程序博客网 时间:2024/06/15 15:53

Description

Input

第1行包含5个整数,依次为 x_0,a,b,c,d ,描述小H采用的随机数生成算法所需的随机种子。第2行包含三个整数 N,M,Q ,表示小H希望生成一个1到 N×M 的排列来填入她 N 行 M 列的棋盘,并且小H在初始的 N×M 次交换操作后,又进行了 Q 次额外的交换操作。接下来 Q 行,第 i 行包含两个整数 u_i,v_i,表示第 i 次额外交换操作将交换 T_(u_i )和 T_(v_i ) 的值。

Output

输出一行,包含 N+M-1 个由空格隔开的正整数,表示可以得到的字典序最小的路径序列。

Sample Input

1 3 5 1 71
3 4 3
1 7
9 9
4 9

Sample Output

1 2 6 8 9 12

HINT


本题的空间限制是 256 MB,请务必保证提交的代码运行时所使用的总内存空间不超过此限制。


一个32位整数(例如C/C++中的int和Pascal中的Longint)为4字节,因而如果在程序中声明一个长度为 1024×1024 的32位整型变量的数组,将会占用 4 MB 的内存空间。


2≤N,M≤5000


0≤Q≤50000


0≤a≤300


0≤b,c≤108


0≤x0<d≤1081≤ui,vi≤N×M

Source

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

贪心+暴力+思路~

先按照题目描述写出数列,再贪心地从小到大枚举每个数字是否能被取,如果能的话就标记所有取了这个数后就不能被取的数。

要注意的是这里标记到已经标记过的数后就要跳出,50s的题,T一下还是很壮观的。

另外x0要开成long long,否则会RE。


#include<cstdio>#include<cstring>#include<iostream>using namespace std;#define ll long longint n,m,Q,q[5001*5001],id[5001*5001],x,y,tot;ll x0,A,B,C,D;bool b[5001][5001];ll read(){ll 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-'0';ch=getchar();}return x*f;}void biao(int u){for(int i=1;i<x;i++)  for(int j=y+1;j<=m;j++)  {  if(b[i][j]) break;b[i][j]=1;  }for(int i=x+1;i<=n;i++)  for(int j=y-1;j;j--)  {  if(b[i][j]) break;b[i][j]=1;  }}int main(){x0=read();A=read();B=read();C=read();D=read();n=read();m=read();Q=read();for(int i=1;i<=n*m;i++) q[i]=i;for(int i=1;i<=n*m;i++){x0=(A*x0*x0+B*x0+C)%D;swap(q[i],q[(x0%i)+1]);}for(int i=1;i<=Q;i++) x=read(),y=read(),swap(q[x],q[y]);for(int i=1;i<=n*m;i++) id[q[i]]=i;for(int i=1;tot<n+m-1;i++){x=id[i]/m,y=id[i]%m;x++;if(!y) x--,y=m;if(b[x][y]) continue;printf("%d",i);biao(i);tot++;if(tot!=n+m-1) printf(" ");}return 0;}