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\n",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\n",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\n",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\n",o,L,R,l,r);
    if(L<=l&&r<=R){
        // printf("ttt\n");
        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\n");
    pushdown(o);
    // printf("ggg!\n");
    int mid=Seg[o].midx;
    // printf("mid=%I64d\n",mid);
    if(L<=mid){
        // printf("%I64d to-L\n",o);
        set1(L,R,Seg[o].lson);}
    if(R>mid){
        // printf("%I64d to-R\n",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 \n",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("\n");
    root=build(1,aft_cnt);
    // debug(root);
    // printf("\n\n\n\n");
    for(int i=1;i<=n;i++){
        if(qx[i].opt==1){
            // printf("optnum=%I64d l=%I64d r=%I64d\n",i,qx[i].l,qx[i].r);
            set1(qx[i].l,qx[i].r,root);
            // debug(root);
            // printf("\n\n\n\n");
            printf("%I64d\n",Seg[root].firz);
        }
        else if(qx[i].opt==2){
            // printf("optnum=%I64d l=%I64d r=%I64d\n",i,qx[i].l,qx[i].r);
            set0(qx[i].l,qx[i].r,root);
            // debug(root);
            // printf("\n\n\n\n");
            printf("%I64d\n",Seg[root].firz);
        }
        else{
            // printf("optnum=%I64d l=%I64d r=%I64d\n",i,qx[i].l,qx[i].r);
            revs(qx[i].l,qx[i].r,root);
            // debug(root);
            // printf("\n\n\n\n");
            printf("%I64d\n",Seg[root].firz);
        }
    }
    return 0;
}
上一篇:matlab2016a安装MinGW


下一篇:倒排索引介绍