noip2019集训测试赛(三)B.mex

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/tylon2006/article/details/100537284

Description

给你一个无限长的数组,初始的时候都为0,有3种操作:

操作1是把给定区间[l,r] 设为1,

操作2是把给定区间[l,r] 设为0,

操作3把给定区间[l,r] 0,1反转。

一共n个操作,每次操作后要输出最小位置的0。


Input

第一行一个整数n,表示有n个操作

接下来n行,每行3个整数op,l,r表示一个操作


Output

共n行,一行一个整数表示答案


Solution

考场上写挂了,没判端点重复。。。

其实不难,就一个离散化加线段树维护所有操作的l,r。
输入所有操作再离散化,用l,r建线段树即可。

注意一下将所有右端点r加1,找区间端点时直接用lower_bound查找第一个大于等于r+1的数的上一个数即可。


Code

#include<bits/stdc++.h>
#define inf 0x7fffffff
using namespace std;
int minn[800010][2];
int laz[800010];
bool lazr[800010];
void pushdown(int id,int l,int r){
    int mid=(l+r)>>1;
    if(laz[id]!=-1){
        int x=laz[id];
        minn[id*2][x]=l;
        minn[id*2+1][x]=mid+1;
        minn[id*2][x^1]=minn[id*2+1][x^1]=inf;
        laz[id*2]=laz[id*2+1]=laz[id];
        lazr[id*2]=lazr[id*2+1]=0;
        laz[id]=-1;
    }
    if(lazr[id]){
        lazr[id*2]^=1,lazr[id*2+1]^=1;
        swap(minn[id*2][0],minn[id*2][1]);
        swap(minn[id*2+1][0],minn[id*2+1][1]);
        lazr[id]=0;
    }
}
void build(int id,int l,int r){
    laz[id]=-1;
    minn[id][0]=l;
    minn[id][1]=inf;
    if(l==r) return;
    int mid=(l+r)>>1;
    build(id*2,l,mid);
    build(id*2+1,mid+1,r);
}
void update1(int id,int l,int r,int ul,int ur,int x){
    if(ul<=l&&r<=ur){
        minn[id][x]=l;
        minn[id][x^1]=inf;
        laz[id]=x;
        lazr[id]=0;
        return;
    }
    pushdown(id,l,r);
    int mid=(l+r)>>1;
    if(ul<=mid) update1(id*2,l,mid,ul,ur,x);
    if(ur>mid) update1(id*2+1,mid+1,r,ul,ur,x);
    minn[id][0]=min(minn[id*2][0],minn[id*2+1][0]);
    minn[id][1]=min(minn[id*2][1],minn[id*2+1][1]);
}
void update2(int id,int l,int r,int ul,int ur){
    if(ul<=l&&r<=ur){
        swap(minn[id][0],minn[id][1]);
        lazr[id]^=1; 
        return;
    }
    pushdown(id,l,r);
    int mid=(l+r)>>1;
    if(ul<=mid) update2(id*2,l,mid,ul,ur);
    if(ur>mid) update2(id*2+1,mid+1,r,ul,ur);
    minn[id][0]=min(minn[id*2][0],minn[id*2+1][0]);
    minn[id][1]=min(minn[id*2][1],minn[id*2+1][1]);
}
struct data{
    int op;
    long long x,y;
}q[100010];
long long b[200020];
int n,tot=0;
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        int x;
        long long y,z;
        scanf("%d%lld%lld",&x,&y,&z);
        q[i]=(data){x,y,z};
        tot++,b[tot]=y,tot++,b[tot]=z+1;
    }
    tot++,b[tot]=1;
    sort(b+1,b+tot+1);
    build(1,1,tot);
    for(int i=1;i<=n;i++){
        int l=lower_bound(b+1,b+tot+1,q[i].x)-b;
        int r=lower_bound(b+1,b+tot+1,q[i].y+1)-b-1;
        if(q[i].op==1) update1(1,1,tot,l,r,1);
        if(q[i].op==2) update1(1,1,tot,l,r,0);
        if(q[i].op==3) update2(1,1,tot,l,r);
        printf("%lld\n",b[minn[1][0]]);
    }
}

猜你喜欢

转载自blog.csdn.net/tylon2006/article/details/100537284
今日推荐