bzoj3671: [Noi2014]随机数生成器

贪心乱搞?

读完题感觉题面好神奇

然后现暴力求出格子排列

然后从1开始枚举看能否加入,若可以把其左下右上所有点标记(用bool否则超空间)

每个点至多被记一次,所以复杂度为O(n*m),常数好像较大

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<string>
#include<map>
using namespace std;
bool st;
int x0,a,b,c,d;
int n,m,q,op;
int cnt=0;
int ui[50005],vi[50005];
int kp[5002][5002];
bool acad[5002][5005];
int chao[25000005];
bool sd;
void change(int sign1,int sign2)
{
     int sx1,sx2,sy1,sy2,k;
     sx1=sign1/m;
     if(sign1%m==0)sy1=m;
     else {sx1++;sy1=sign1%m;}
     sx2=sign2/m;
     if(sign2%m==0)sy2=m;
     else {sx2++;sy2=sign2%m;}
     k=kp[sx1][sy1];  
     kp[sx1][sy1]=kp[sx2][sy2];
     kp[sx2][sy2]=k;
}  
void lcr(int l,int r)
{
     int i,j;
     l++;r--;
     for(i=l;i<=n;i++){
         if(!acad[i][r])break;
         for(j=r;j>=1;j--){
             if(acad[i][j])acad[i][j]=false;
             else break;
             }
         }
     l-=2;r+=2;
     for(i=l;i>=1;i--){
         if(!acad[i][r])break;
         for(j=r;j<=m;j++){
             if(acad[i][j])acad[i][j]=false;
             else break;
             }
         }
}
int main()
{
    freopen("random.in","r",stdin);
    freopen("random.out","w",stdout);
    int i,j,k,sx,sy;
    scanf("%d%d%d%d%d",&x0,&a,&b,&c,&d);
    scanf("%d%d%d",&n,&m,&q);
    for(i=1;i<=q;i++)scanf("%d%d",&ui[i],&vi[i]);
    for(i=1;i<=n;i++)
        for(j=1;j<=m;j++){
            kp[i][j]=(i-1)*m+j;
            acad[i][j]=true;
            }
    for(i=1;i<=n*m;i++){
        x0=((long long)a*x0*x0+(long long)b*x0+c)%d;
        change(x0%i+1,i);
        }
    for(i=1;i<=q;i++)
         change(ui[i],vi[i]);    
    for(i=1;i<=n;i++)
        for(j=1;j<=m;j++)
            chao[kp[i][j]]=(i-1)*m+j;
    for(i=1;i<=n*m;i++){
        sx=chao[i]/m;
        if(chao[i]%m==0)sy=m;
        else {sx++;sy=chao[i]%m;}
        if(acad[sx][sy]){
           lcr(sx,sy);
           cnt++;
           printf("%d ",i);
           }
        if(cnt==(n+m-1))break;
        }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值