【XSY2484】mex

Description

Give you an infinite array, the initial time are zero, there are three modes of operation:

1 is given to the operation interval [l, r] is set to 1,

2 is given to the operation interval [l, r] is set to 0,

Operation 3 given interval [l, r] 0,1 reversed.

A total of n operation, the operation to output 0 after each minimum position.

Input

A first line integer n, there are n represents operation

Next n lines, each line three integers op, l, r represents an operation

Output

A total of n rows, one row represents an integer answer

Sample Input

3
1 3 4
3 1 6
2 1 3

Sample Output

1
3
1

HINT

For 30% of the data 1≤n≤1000,1≤l≤r≤1e18

To 100% data 1≤n≤100000,1≤l≤r≤1e18

l, r up to 1e18, will certainly be discrete.

There are a large number of modified operating range - consider the tree line

Solution:

+ Discrete segment tree

First of all discrete.

The interval l per pass, r, r + 1 when placed in a discrete array. lower_bound discretization, obtained after discretization l, r.

Why should we put r + 1?

As such, the discrete, 1-2, 3-4 intervals are 1, should have had the presence of 0, but the segment did not have a tree, this time we should use this r + 1 "hole" to fill .

After discretization:

Recording segment tree minn [i] [0], minn [i] [1], and 0 represents the interval at which a first point appears, if not occurred, minn = INF;

Operation 2: Modify interval minn [i] [0], minn [i] [1], sum [i] lazy marker.

Operation 3: exchange minn [i] [0], minn [i] [1], lazy [i] records are lazy flag changes it back, if not change back, pushdown.

The overall idea is this, a little difficult to debug the code, you must be patient and play, carefully transfer.

#include<bits/stdc++.h>
#define inf 1e9
using namespace std;
struct data
{
    int op;
    long long l,r;
}q[2000001];
int lazy[2000001],minn[2000001][2],sum[2000001],op,n,cnt,cnt1;
long long l,r,b[2000001];
void build(int hao,int l,int r)
{
    lazy[hao]=0;
    sum[hao]=-1;
    minn[hao][0]=l;
    minn[hao][1]=inf;//一开始全部是0
    if(l==r)
    {
        return;
    }
    int mid=(l+r)/2;
    build(hao<<1,l,mid);
    build(hao<<1|1,mid+1,r);
}
void pushdown(int hao,int l,int r)
{
    int mid=(l+r)/2;
    if(sum[hao]!=-1)//下放sum
    {
        int p=sum[hao];
        sum[hao<<1]=sum[hao<<1|1]=p;
        lazy[hao<<1]=lazy[hao<<1|1]=0;//直接赋值,lazy清零
        minn[hao<<1][p]=l;
        minn[hao<<1|1][p]=mid+1;
        minn[hao<<1][p^1]=inf;
        minn[hao<<1|1][p^1]=inf;
        sum[hao]=-1;
    }
    if(lazy[hao])//下放lazy
    {
        lazy[hao<<1]^=1;
        lazy[hao<<1|1]^=1;
        swap(minn[hao<<1][0],minn[hao<<1][1]);
        swap(minn[hao<<1|1][0],minn[hao<<1|1][1]);
        lazy[hao]=0;
    }
}
void update(int hao,int l,int r,int L,int R,int num)//操作1,2
{
    if(L<=l&&R>=r)
    {
        sum[hao]=num;
        minn[hao][num]=l;
        lazy[hao]=0;//直接赋值,lazy清零
        minn[hao][num^1]=inf;
    }else{
        pushdown(hao,l,r);
        int mid=(l+r)/2;
        if(L<=mid)
        {
            update(hao<<1,l,mid,L,R,num);
        }
        if(R>mid)
        {
            update(hao<<1|1,mid+1,r,L,R,num);                                             
        }
        minn[hao][0]=min(minn[hao<<1][0],minn[hao<<1|1][0]);
        minn[hao][1]=min(minn[hao<<1][1],minn[hao<<1|1][1]);
    }
}
void change(int hao,int l,int r,int L,int R)//操作3
{
    if(L<=l&&R>=r)
    {
        lazy[hao]^=1;
        swap(minn[hao][0],minn[hao][1]);
    }else{
        pushdown(hao,l,r);
        int mid=(l+r)/2;
        if(L<=mid)
        {
            change(hao<<1,l,mid,L,R);
        }
        if(R>mid)
        {
            change(hao<<1|1,mid+1,r,L,R);
        }
        minn[hao][0]=min(minn[hao<<1][0],minn[hao<<1|1][0]);
        minn[hao][1]=min(minn[hao<<1][1],minn[hao<<1|1][1]);
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%lld%lld",&op,&l,&r);
        q[i].op=op;
        q[i].l=l;
        q[i].r=r;
        b[++cnt]=l;
        b[++cnt]=r;
        b[++cnt]=r+1;
    }
    b[++cnt]=1;
    sort(b+1,b+cnt+1);
    b[0]=-0x7f7f7f7f;
    for(int i=1;i<=cnt;i++)//去重
    {
        if(b[i]==b[i-1])
        {
            continue;
        }
        b[++cnt1]=b[i];
    }
    cnt=cnt1;
    build(1,1,cnt);
    for(int i=1;i<=n;i++)
    {
        int l=lower_bound(b,b+cnt+1,q[i].l)-b;//离散化
        int r=lower_bound(b,b+cnt+1,q[i].r+1)-b-1;
        if(q[i].op==1)
        {
            update(1,1,cnt,l,r,1);
        }else{
            if(q[i].op==2)
            {
                update(1,1,cnt,l,r,0);
            }else{
                change(1,1,cnt,l,r);
            }
        }
        printf("%lld\n",b[minn[1][0]]);
    }
    return 0;
}
/*
3
1 3 4
3 1 6
2 1 3
*/

Guess you like

Origin www.cnblogs.com/2017gdgzoi44/p/11348762.html