• CF817F MEX Queries


    思路

    下次记住,这种求mex一类哪个没有出现的都可以用值域线段树维护一个sz然后树上二分的
    我为啥偏偏要维护每个节点对应区间的第一个未出现的0和1的位置啊(捂脸
    我是傻逼,这样难写还难调

    代码

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #define int long long
    using namespace std;
    struct Node{
        int firz,firo,lson,rson,allz,allo,inv,set,lx,rx,midx;
    }Seg[500000<<2];//0 特殊处理
    struct Ask{
        int opt,l,r;
    }qx[110000];
    int Nodecnt,root,pos[500000],cnt,aft_cnt,n;
    void pushup(int o){
        Seg[o].allo=Seg[Seg[o].lson].allo&&Seg[Seg[o].rson].allo;
        Seg[o].allz=Seg[Seg[o].lson].allz&&Seg[Seg[o].rson].allz;
        Seg[o].firo=min(Seg[Seg[o].lson].firo,Seg[Seg[o].rson].firo);
        Seg[o].firz=min(Seg[Seg[o].lson].firz,Seg[Seg[o].rson].firz);
    }
    int New_Node(int l,int mid,int r){
        ++Nodecnt;
        Seg[Nodecnt].allo=0;
        Seg[Nodecnt].allz=1;
        Seg[Nodecnt].firo=9000000000000000000LL;
        Seg[Nodecnt].firz=l;
        Seg[Nodecnt].inv=0;
        Seg[Nodecnt].lx=l;
        Seg[Nodecnt].rx=r;
        Seg[Nodecnt].set=-1;
        Seg[Nodecnt].midx=mid;
        return Nodecnt;
    }
    void pushdown(int o){
        if(Seg[o].inv){
            swap(Seg[Seg[o].lson].allo,Seg[Seg[o].lson].allz);
            swap(Seg[Seg[o].lson].firo,Seg[Seg[o].lson].firz);
            swap(Seg[Seg[o].rson].allo,Seg[Seg[o].rson].allz);
            swap(Seg[Seg[o].rson].firo,Seg[Seg[o].rson].firz);
            if(Seg[Seg[o].lson].set!=-1)
                Seg[Seg[o].lson].set^=1;
            else
                Seg[Seg[o].lson].inv^=1;
            if(Seg[Seg[o].rson].set!=-1)
                Seg[Seg[o].rson].set^=1;
            else
                Seg[Seg[o].rson].inv^=1;
            Seg[o].inv=0;
        }
        if(Seg[o].set!=-1){
            if(Seg[o].set==0){
                Seg[Seg[o].lson].allo=0;
                Seg[Seg[o].lson].allz=1;
                Seg[Seg[o].lson].firo=9000000000000000000LL;
                Seg[Seg[o].lson].firz=Seg[Seg[o].lson].lx;
                Seg[Seg[o].lson].set=Seg[o].set; 
                Seg[Seg[o].lson].inv=0;
                Seg[Seg[o].rson].allo=0;
                Seg[Seg[o].rson].allz=1;
                Seg[Seg[o].rson].firo=9000000000000000000LL;
                Seg[Seg[o].rson].firz=Seg[Seg[o].rson].lx;
                Seg[Seg[o].rson].set=Seg[o].set; 
                Seg[Seg[o].rson].inv=0;
            }   
            if(Seg[o].set==1){
                Seg[Seg[o].lson].allo=1;
                Seg[Seg[o].lson].allz=0;
                Seg[Seg[o].lson].firo=Seg[Seg[o].lson].lx;
                Seg[Seg[o].lson].firz=9000000000000000000LL;
                Seg[Seg[o].lson].set=Seg[o].set; 
                Seg[Seg[o].lson].inv=0;
                Seg[Seg[o].rson].allo=1;
                Seg[Seg[o].rson].allz=0;
                Seg[Seg[o].rson].firo=Seg[Seg[o].rson].lx;
                Seg[Seg[o].rson].firz=9000000000000000000LL;
                Seg[Seg[o].rson].set=Seg[o].set; 
                Seg[Seg[o].rson].inv=0;
            }
            Seg[o].set=-1;
        }
        
    }
    int query(int L,int R,int o){
        int l=Seg[o].lx,r=Seg[o].rx;
        if(R<l||L>r)
            return 9000000000000000000LL;
        if(L<=l&&r<=R){
            return Seg[o].firz;
        }
        int mid=Seg[o].midx;
        pushdown(o);
        int ans=9000000000000000000LL;
        if(L<=mid)
            ans=min(ans,query(L,R,Seg[o].lson));
        if(R>mid)
            ans=min(ans,query(L,R,Seg[o].rson));
        return ans;
    }
    void revs(int L,int R,int o){
        int l=Seg[o].lx,r=Seg[o].rx;
        if(R<l||L>r)
            return;
        if(L<=l&&r<=R){
            swap(Seg[o].allo,Seg[o].allz);
            swap(Seg[o].firo,Seg[o].firz);
            if(Seg[o].set!=-1)
                Seg[o].set^=1;
            else
                Seg[o].inv^=1;
            return;
        }
        pushdown(o);
        int mid=Seg[o].midx;
        if(L<=mid)
            revs(L,R,Seg[o].lson);
        if(R>mid)
            revs(L,R,Seg[o].rson);
        pushup(o);
    }
    void set0(int L,int R,int o){
        if(Seg[o].allz)
            return;
        int l=Seg[o].lx,r=Seg[o].rx;
        if(R<l||L>r)
            return;
        // printf("l=%I64d r=%I64d o=%I64d
    ",l,r,o);
        if(L<=l&&r<=R){
            Seg[o].allo=0;
            Seg[o].allz=1;
            Seg[o].firo=9000000000000000000LL;
            Seg[o].firz=Seg[o].lx;
            Seg[o].set=0; 
            Seg[o].inv=0;
            return;
        }
        pushdown(o);
        int mid=Seg[o].midx;
        if(L<=mid)
            set0(L,R,Seg[o].lson);
        if(R>mid)
            set0(L,R,Seg[o].rson);
        // printf("l=%I64d r=%I64d o=%I64d firz=%I64d
    ",l,r,o,Seg[o].firz);
        pushup(o);
    }
    void set1(int L,int R,int o){
        // printf("o=%I64d want %I64d %I64d became-1 %I64d %I64d
    ",o,L,R,l,r);
        if(Seg[o].allo)
            return;
        int l=Seg[o].lx,r=Seg[o].rx;
        if(R<l||L>r)
            return;
        // printf("o=%I64d want %I64d %I64d became-1 %I64d %I64d
    ",o,L,R,l,r);
        if(L<=l&&r<=R){
            // printf("ttt
    ");
            Seg[o].allo=1;
            Seg[o].allz=0;
            Seg[o].firo=Seg[o].lx;
            Seg[o].firz=9000000000000000000LL;
            Seg[o].set=1; 
            Seg[o].inv=0;
            return;
        }
        // printf("ggg
    ");
        pushdown(o);
        // printf("ggg!
    ");
        int mid=Seg[o].midx;
        // printf("mid=%I64d
    ",mid);
        if(L<=mid){
            // printf("%I64d to-L
    ",o);
            set1(L,R,Seg[o].lson);}
        if(R>mid){
            // printf("%I64d to-R
    ",o);
            set1(L,R,Seg[o].rson);}
        pushup(o);
    }
    int build(int l,int r){
        // printf("build")
        int newx=New_Node(pos[l],pos[(l+r)>>1],pos[r]);
        if(l!=r){
            int mid=(l+r)>>1;
            Seg[newx].lson=build(l,mid);
            Seg[newx].rson=build(mid+1,r);
            pushup(newx);
        }
        return newx;
    }
    void debug(int o){ 
        int l=Seg[o].lx,r=Seg[o].rx;
        printf("o=%I64d lson=%I64d rson=%I64d lx=%I64d rx=%I64d firz=%I64d firo=%I64d allz=%I64d allo=%I64d 
    ",o,Seg[o].lson,Seg[o].rson,Seg[o].lx,Seg[o].rx,Seg[o].firz,Seg[o].firo,Seg[o].allz,Seg[o].allo);
        if(l!=r){
            debug(Seg[o].lson);
            debug(Seg[o].rson);
        }
    }
    signed main(){
        scanf("%I64d",&n);
        pos[++cnt]=1;
        for(int i=1;i<=n;i++){
            scanf("%I64d %I64d %I64d",&qx[i].opt,&qx[i].l,&qx[i].r);
            // cout<<9000000000000000000LL<<endl;
            if(qx[i].l-1>0)
                pos[++cnt]=qx[i].l-1;
            pos[++cnt]=qx[i].l;
            pos[++cnt]=qx[i].r;
            pos[++cnt]=qx[i].r+1;
        }
        sort(pos+1,pos+cnt+1);
        aft_cnt=unique(pos+1,pos+cnt+1)-(pos)-1;
        // for(int i=1;i<=aft_cnt;i++)
        //     printf("%I64d ",pos[i]);
        // printf("
    ");
        root=build(1,aft_cnt);
        // debug(root);
        // printf("
    
    
    
    ");
        for(int i=1;i<=n;i++){
            if(qx[i].opt==1){
                // printf("optnum=%I64d l=%I64d r=%I64d
    ",i,qx[i].l,qx[i].r);
                set1(qx[i].l,qx[i].r,root);
                // debug(root);
                // printf("
    
    
    
    ");
                printf("%I64d
    ",Seg[root].firz);
            }
            else if(qx[i].opt==2){
                // printf("optnum=%I64d l=%I64d r=%I64d
    ",i,qx[i].l,qx[i].r);
                set0(qx[i].l,qx[i].r,root);
                // debug(root);
                // printf("
    
    
    
    ");
                printf("%I64d
    ",Seg[root].firz);
            }
            else{
                // printf("optnum=%I64d l=%I64d r=%I64d
    ",i,qx[i].l,qx[i].r);
                revs(qx[i].l,qx[i].r,root);
                // debug(root);
                // printf("
    
    
    
    ");
                printf("%I64d
    ",Seg[root].firz);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    hdu2222 AC自动机入门
    bzoj1095: [ZJOI2007]Hide 捉迷藏 动态点分治学习
    【NOI2014】起床困难综合症 贪心
    bzoj1822: [JSOI2010]Frozen Nova 冷冻波网络流
    洛谷3767 膜法 带权并查集+分治
    NOI2015品酒大会 后缀数组
    NOI2015程序自动分析 并查集
    NOI2015软件包管理器 树剖线段树
    51nod1244 欧拉函数之和 杜教筛
    51nod1244 莫比乌斯函数之和 杜教筛
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10526715.html
Copyright © 2020-2023  润新知