ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF817F MEX Queries

2019-03-13 21:37:44  阅读:232  来源: 互联网

标签:return int rson Queries pos Seg CF817F I64d MEX


思路

下次记住,这种求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;
}

标签:return,int,rson,Queries,pos,Seg,CF817F,I64d,MEX
来源: https://www.cnblogs.com/dreagonm/p/10526715.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有