zoukankan      html  css  js  c++  java
  • 【题解】LOJ#541. 「LibreOJ NOIP Round #1」七曜圣贤【乱搞】

    题目链接

    题意

    维护一个集合,初始为 \([0,a]\cap \mathbf{N}\),要求支持以下操作:

    1. 插入 \(x\),保证 \(x\) 未被加入过;
    2. 删除 \(x\)
    3. 把最近一次删除时间最早的、不在集合中的数插入回矩阵。

    求每一次操作后集合的 \(\operatorname{mex}\)

    多组数据,数据由随机数生成器生成,其中有参数可以控制操作 3 的频率。

    \(m\leq 10^6\)\(T\leq 50\)

    题解

    标算是 \(O(mT)\) 的,这里有一种 \(O(\text{玄学})\) 的做法:

    • 由于数据随机,维护 \(ans\),直接在操作 1、3 时暴力移 \(ans\),操作 2 时 \(ans\gets \min(ans,x)\)
    • 对于 \(c=2\)\(a\) 较大的情况,操作 \(3\) 占了几乎一半,于是集合整体不会被分成很多段,用 set 维护桶的差分。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    long long getint(){
        long long ans=0,f=1;
        char c=getchar();
        while(c<'0'||c>'9'){
            if(c=='-')f=-1;
            c=getchar();
        }
        while(c>='0'&&c<='9'){
            ans=ans*10+c-'0';
            c=getchar();
        }
        return ans*f;
    }
    const int M=2e6+10,mod=998244353;
    int m,a,b,c,d;
    unsigned int seed;
    inline unsigned int randnum(){
        seed^=(seed<<13);
        seed^=(seed>>17);
        seed^=(seed<<5);
        return seed;
    }
    inline int getp(){
        if(randnum()%c==0)return -1;
        else return randnum()%b;
    }
    
    bool f[M<<1],g[M<<1];
    int ans=0;
    struct que{
        int a[M];
        int *l,*r;
        que(){ l=r=a; }
        inline void push(int x){ *(r++)=x; }
        inline void pop(){ l++; }
        inline int size(){ return r-l; }
        inline void init(){ l=r=a; }
        inline int front(){ return *l; }
    };
    que q;
    
    set<int>s;
    void modi(int x){
    	if(s.count(x))s.erase(x);
    	else s.insert(x);
    }
    inline void op1(int p){
    	f[p]=g[p]=1;
    	if(c>2){
    	    while(f[ans])++ans;
    	}else{
    		modi(p);modi(p+1);
    		set<int>::iterator b=s.begin();
    		if(*b==0)ans=*(++b);
    		else ans=0;
    	}
    }
    inline void op2(int p){
        f[p]=0;
        if(c>2){}else{
    		modi(p);modi(p+1);
    		if(s.size()){
    			set<int>::iterator b=s.begin();
    			if(*b==0)ans=*(++b);
    			else ans=0;
    		}else ans=0;
    	}
    	q.push(p);
    	ans=min(ans,p);
    }
    inline void op3(){
        op1(q.front());
        q.pop();
    }
    
    int main(){
        int T=getint();
        while(T --> 0){
            m=getint(),seed=getint(),a=getint(),b=getint(),c=getint(),d=getint();
    		for(int i=0;i<=a;i++)f[i]=g[i]=1;ans=a+1;
    		if(c<=2)s.insert(0),s.insert(a+1);
            long long res=0;
            for(int i=1;i<=m;i++){
                int p=getp();
                if(p==-1){
                    if(!q.size())continue;
                    if(d)continue; else op3();
                }else{
                    if(!g[p]){ op1(p); }
                    else if(f[p]){ if(d)continue;else op2(p); }
                    else if(q.size()){ if(d)continue;else op3(); }
                    else continue;
                }
                res^=ans*(i*1ll*i%mod+7ll*i%mod)%mod;
            }
            printf("%lld\n",res);
            q.init();
            memset(f,0,sizeof(bool)*(b+2));
            memset(g,0,sizeof(bool)*(b+2));
            s.clear();
        }
    }
    
    知识共享许可协议
    若文章内无特别说明,公开文章采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
  • 相关阅读:
    SQL2008-表对表直接复制数据
    delphi debug release区别是什么?
    javascript中的for in循环和for in循环的使用陷阱
    JS操作DOM节点大全
    JS中for循环里面的闭包问题的原因及解决办法
    使用sessionStorage、localStorage存储数组与对象
    JS中substr和substring的用法和区别
    HBuilder使用夜神模拟器调试Android应用
    JSON.parse()和JSON.stringify()
    url中的特殊符号含义
  • 原文地址:https://www.cnblogs.com/wallbreaker5th/p/13778163.html
Copyright © 2011-2022 走看看