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
分析: NOI14最让我伤心的一道题了,考场上读错题最后只拿了十分,直接导致我CU滚粗。。。。很水的一道题,直接暴力就能过。。。艹
/**************************************************************
Problem: 3671
User: WZJRJ28
Language: C++
Result: Accepted
Time:31644 ms
Memory:221244 kb
****************************************************************/
#define INF 2147483647
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
long long a,b,c,d,t,u_i,v_i,x;
int N,M,Q,T[5001*5001+1],F[5001*5001+1];
bool hash[5001*5001+1];
struct Rec
{
int x;
int y;
int n;
int m;
};
Rec z[5000+5000+3];
void Delete(int x,int y,int n,int m)
{
for(int i=x;i<=n;i++)
for(int j=y;j<=m;j++)
hash[T[(i-1)*M+j]]=true;
}
int main()
{
cin>>x>>a>>b>>c>>d;
cin>>N>>M>>Q;
for(int i=1;i<=N*M;i++) T[i]=i;
for(int i=1;i<=N*M;i++)
{
x=(a*x*x+b*x+c)%d;
swap(T[i],T[x%i+1]);
}
for(int i=1;i<=Q;i++)
{
cin>>u_i>>v_i;
swap(T[u_i],T[v_i]);
}
for(int i=1;i<=N*M;i++) F[T[i]]=i;
t=1;
z[1].x=1;
z[1].y=1;
z[1].n=N;
z[1].m=M;
for(int i=1;i<=N*M;i++)
if(!hash[i])
{
int X=(F[i]-1)/M+1,Y=F[i]%M;
if(!Y) Y=M;
for(int j=1;j<=t;j++)
if(z[j].x<=X && X<=z[j].n && z[j].y<=Y && Y<=z[j].m)
{
Delete(X+1,z[j].y,z[j].n,Y-1);
Delete(z[j].x,Y+1,X-1,z[j].m);
t++;
z[t].n=z[j].n;
z[t].m=z[j].m;
z[j].n=X;
z[j].m=Y;
z[t].x=X;
z[t].y=Y;
break;
}
}
bool flag=false;
for(int i=1;i<=N*M;i++)
if(!hash[i])
{
if(flag) cout<<" ";
cout<<i;
flag=true;
}
}