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
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;
}