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;
}
posted @ 2019-06-19 18:04  风浔凌  阅读(193)  评论(0编辑  收藏  举报