zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 23 F. MEX Queries 离散化+线段树

    F. MEX Queries
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    You are given a set of integer numbers, initially it is empty. You should perform n queries.

    There are three different types of queries:

    • l r — Add all missing numbers from the interval [l, r]
    • l r — Remove all present numbers from the interval [l, r]
    • l r — Invert the interval [l, r] — add all missing and remove all present numbers from the interval [l, r]

    After each query you should output MEX of the set — the smallest positive (MEX  ≥ 1) integer number which is not presented in the set.

    Input

    The first line contains one integer number n (1 ≤ n ≤ 105).

    Next n lines contain three integer numbers t, l, r (1 ≤ t ≤ 3, 1 ≤ l ≤ r ≤ 1018) — type of the query, left and right bounds.

    Output

    Print MEX of the set after each query.

    Examples
    input
    3
    1 3 4
    3 1 6
    2 1 3
    output
    1
    3
    1
    input
    4
    1 1 3
    3 5 6
    2 4 4
    3 1 6
    output
    4
    4
    4
    1
    Note

    Here are contents of the set after each query in the first example:

    1. {3, 4} — the interval [3, 4] is added
    2. {1, 2, 5, 6} — numbers {3, 4} from the interval [1, 6] got deleted and all the others are added
    3. {5, 6} — numbers {1, 2} got deleted

    题意:给你n个区间,1操作表示把[l,r]赋值为1,2操作表示把[l,r]赋值为0,3操作表示把[l,r]异或1;

         求第一个不为0的正整数。

    思路:对于所有区间[l,r]取出l,r,r+1三个点;

       离散化放入线段树中去

       现在需要区间修改,区间异或,查询

       需要两个lazy标记,一个存修改的值,一个存是否异或1.

       区间查询log查找即可,详见代码。

       小trick:需要加入最小值,即是1的情况;

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<stack>
    #include<cstring>
    #include<vector>
    #include<list>
    #include<set>
    #include<map>
    #include<bitset>
    #include<time.h>
    using namespace std;
    #define LL long long
    #define pi (4*atan(1.0))
    #define eps 1e-4
    #define bug(x)  cout<<"bug"<<x<<endl;
    const int N=3e5+10,M=4e6+10,inf=2147483647,mod=1e9+7;
    const LL INF=1e18+10,MOD=1e9+7;
    
    int L=3e5+10;
    struct LT
    {
        int sum[N<<2],to[N<<2],sw[N<<2];
        void pushdown(int pos,int l,int r)
        {
            int mid=(l+r)>>1;
            if(to[pos]!=-1)
            {
                to[pos<<1]=to[pos];
                to[pos<<1|1]=to[pos];
                sum[pos<<1]=to[pos]*(mid-l+1);
                sum[pos<<1|1]=to[pos]*(r-mid);
                to[pos]=-1;
                sw[pos]=0;
            }
            if(sw[pos])
            {
                if(to[pos<<1]!=-1)to[pos<<1]=!to[pos<<1];
                else sw[pos<<1]=!sw[pos<<1];
                if(to[pos<<1|1]!=-1)to[pos<<1|1]=!to[pos<<1|1];
                else sw[pos<<1|1]=!sw[pos<<1|1];
                sum[pos<<1]=(mid-l+1)-sum[pos<<1];
                sum[pos<<1|1]=(r-mid)-sum[pos<<1|1];
                sw[pos]=0;
            }
        }
        void build(int l,int r,int pos)
        {
            to[pos]=-1;
            sw[pos]=0;
            sum[pos]=0;
            if(l==r)return;
            int mid=(l+r)>>1;
            build(l,mid,pos<<1);
            build(mid+1,r,pos<<1|1);
        }
        void update(int L,int R,int c,int l,int r,int pos)
        {
            if(L<=l&&r<=R)
            {
                if(c==2)
                {
                    if(to[pos]!=-1)to[pos]=!to[pos];
                    else sw[pos]=!sw[pos];
                }
                else
                {
                    to[pos]=c;
                    sw[pos]=0;
                }
                if(c==2)sum[pos]=r-l+1-sum[pos];
                else sum[pos]=(r-l+1)*c;
                return;
            }
            pushdown(pos,l,r);
            int mid=(l+r)>>1;
            if(L<=mid)update(L,R,c,l,mid,pos<<1);
            if(R>mid) update(L,R,c,mid+1,r,pos<<1|1);
            sum[pos]=sum[pos<<1|1]+sum[pos<<1];
        }
        int query(int l,int r,int pos)
        {
            //cout<<l<<" "<<r<<" "<<sum[pos]<<" "<<to[pos]<<endl;
            if(l==r)return l;
            pushdown(pos,l,r);
            //cout<<sum[pos<<1]<<" "<<sum[pos<<1|1]<<endl;
            int mid=(l+r)>>1;
            if(sum[pos<<1]==mid-l+1)return query(mid+1,r,pos<<1|1);
            else return query(l,mid,pos<<1);
        }
    }tree;
    
    int t[N],len;
    LL l[N],r[N],s[N];
    int getpos(LL x)
    {
        int pos=lower_bound(s+1,s+len,x)-s;
        return pos;
    }
    int main()
    {
        int n,k=0;
        scanf("%d",&n);
        s[++k]=1;
        for(int i=1;i<=n;i++)
            scanf("%d%lld%lld",&t[i],&l[i],&r[i]),s[++k]=l[i],s[++k]=r[i],s[++k]=r[i]+1;
        sort(s+1,s+1+k);
        len=unique(s+1,s+1+k)-s;
        tree.build(1,L,1);
        for(int i=1;i<=n;i++)
        {
            int z=getpos(l[i]),y=getpos(r[i]);
            if(t[i]==1)tree.update(z,y,1,1,L,1);
            else if(t[i]==2)tree.update(z,y,0,1,L,1);
            else if(t[i]==3)tree.update(z,y,2,1,L,1);
            int x=tree.query(1,L,1);
            //cout<<"xxx "<<x<<" "<<tree.sum[1]<<endl;
            printf("%lld
    ",s[x]);
        }
        return 0;
    }
  • 相关阅读:
    CentOS虚拟机和物理机共享文件夹实现
    集训第六周 数学概念与方法 概率 数论 最大公约数 G题
    集训第六周 数学概念与方法 概率 F题
    集训第六周 E题
    集训第六周 古典概型 期望 D题 Discovering Gold 期望
    集训第六周 古典概型 期望 C题
    集训第六周 数学概念与方法 UVA 11181 条件概率
    集训第六周 数学概念与方法 UVA 11722 几何概型
    DAG模型(矩形嵌套)
    集训第五周 动态规划 K题 背包
  • 原文地址:https://www.cnblogs.com/jhz033/p/7079334.html
Copyright © 2011-2022 走看看