BZOJ-3671 [Noi2014]随机数生成器

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




分析: 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;
        } 
 } 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值