zoukankan      html  css  js  c++  java
  • 【CodeForces817F】MEX Queries

    题目链接

    MEX Queries

    题目描述

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

    There are three different types of queries:

    • (1 l r) — Add all missing numbers from the interval ([l, r])
    • (2 l r) — Remove all present numbers from the interval ([l, r])
    • (3 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  ge 1)) integer number which is not presented in the set.

    输入格式

    The first line contains one integer number (n) ((1 le n le 10^5)).

    Next (n) lines contain three integer numbers (t, l, r) ((1 le t le 3, 1 le l le r le 10^{18})) — type of the query, left and right bounds.

    输出格式

    Print (MEX) of the set after each query.

    样例输入1

    3
    1 3 4
    3 1 6
    2 1 3
    

    样例输出1

    1
    3
    1
    

    样例输入2

    4
    1 1 3
    3 5 6
    2 4 4
    3 1 6
    

    样例输出2

    4
    4
    4
    1
    

    题解

    题意:维护一个集合,有三种操作,第一种操作将区间([l,r])内所有元素加入集合中;第二种操作将区间([l,r])内所有在集合内的元素从集合中删除;第三种操作将区间([l,r])中所有在集合内的元素删除,不在集合内的元素加入集合。
    要求每次操作后输出最小的没有在集合内的元素。
    很明显是一道线段树水题,每次区间修改加上懒标记就好了。
    但是我们发现这里区间的范围在(1e18)内,所幸修改操作数在(1e5)内,所以我们可以离散化一下。
    因为如果直接离散化(l,r)的话边界情况会比较难处理,每次操作要离散3个点,所以我这里是离散化(l,r+1),把区间离散化而不是把点离散化。
    我们用(i)表示元素(i)和元素(i-1)的交界,那么我们要修改([l,r])的时候就要离散化(l)(l-1)的交界和(r)(r+1)的交界,也就是(l,r+1)两个点。
    上代码:

    #include<bits/stdc++.h>
    using namespace std;
    int n;
    struct aa{
        int t;
        long long l,r;
    }a[500009];
    int lt=1;
    struct cc{
        long long s;
        int from;
        bool k;
    }to[500009];
    struct bb{
        int x;
        int ld;
    }p[4000009];
    bool cmp(cc x,cc y){return x.s<y.s;}
    void dn(int u,int l,int r){
        if(p[u].ld&(1<<2)){
            p[u*2].ld=p[u*2+1].ld=(1<<2);
            p[u].x=r-l;
        }
        if(p[u].ld&(1<<1)){
            p[u*2].ld=p[u*2+1].ld=(1<<1);
            p[u].x=0;
        }
        if(p[u].ld&1){
            p[u].x=r-l-p[u].x;
            if(p[u*2].ld&(1<<2)) p[u*2].ld=(1<<1);
            else if(p[u*2].ld&(1<<1)) p[u*2].ld=(1<<2);
            else p[u*2].ld^=1;
            if(p[u*2+1].ld&(1<<2)) p[u*2+1].ld=(1<<1);
            else if(p[u*2+1].ld&(1<<1)) p[u*2+1].ld=(1<<2);
            else p[u*2+1].ld^=1;
        }
        p[u].ld=0;
    }
    void dfs(int u,int l,int r,int x){
        dn(u,l,r);
        if(r<=a[x].l || l>=a[x].r) return;
        if(l>=a[x].l && r<=a[x].r){
            p[u].ld=(1<<(3-a[x].t));
            dn(u,l,r);
            if(r==l+1) return;
            dn(u*2,l,(l+r)/2);
            dn(u*2+1,(l+r)/2,r);
            p[u].x=p[u*2].x+p[u*2+1].x;
            return;
        }
        if(r==l+1) return;
        dfs(u*2,l,(l+r)/2,x);
        dfs(u*2+1,(l+r)/2,r,x);
        p[u].x=p[u*2].x+p[u*2+1].x;
    }
    void fd(int u,int l,int r){
        dn(u,l,r);
        if(p[u].x==0){
            printf("%lld
    ",to[l].s);
            return;
        }
        else if(p[u].x==r-l){
            printf("%lld
    ",to[r].s);
            return;
        }else{
            dn(u*2,l,(l+r)/2);
            if(p[u*2].x==(l+r)/2-l) fd(u*2+1,(l+r)/2,r);
            else fd(u*2,l,(l+r)/2);
        }
    }
    int main(){
        scanf("%d",&n);
        for(int j=1;j<=n;j++){
            scanf("%d%lld%lld",&a[j].t,&a[j].l,&a[j].r);
            a[j].r++;
            to[j*2-1].s=a[j].l;
            to[j*2-1].from=j;
            to[j*2].s=a[j].r;
            to[j*2].from=j;
            to[j*2].k=1;
        }
        to[n*2+1].s=1;
        sort(to+1,to+n*2+2,cmp);
        if(to[1].k) a[to[1].from].r=1;
        else a[to[1].from].l=1;
        for(int j=2;j<=n*2+1;j++){
            if(to[j].s!=to[lt].s) to[++lt]=to[j];
            if(to[j].k) a[to[j].from].r=lt;
            else a[to[j].from].l=lt;
        }
        for(int j=1;j<=n;j++){
            dfs(1,1,lt,j);
            fd(1,1,lt);
        }
        return 0;
    }
    
  • 相关阅读:
    HDFS under replicated blocks
    docker-compose
    shell $* 和$@ 的区别以及运算操作
    ajax与文件上传
    Django之模型层(多表操作)
    Django之模型层(单表操作)
    Django之模板层
    Django之视图层
    Django之路由层
    Django之web应用、http协议和django简介
  • 原文地址:https://www.cnblogs.com/linjiale/p/13479373.html
Copyright © 2011-2022 走看看