• 线段树 离散区间,单点维护区间


      这道题当时用线段树搞不行,用主席树搞,也不行。当场自闭。。。

      其实当时想到离散,但是没想到用单点维护线段树的区间。。。。。。

      你这样想,无非就是2e6次询问,最多1-e9被分成最多2e6区间,我们要求的位置,一定在这2e6点的右边第一个。

      那么把这个点,以及这个点x以及x+1的点保存下来。

      维护的时候,线段树初始化所有的单点值为1,并维护区间和,代表单点没有被删掉。

      我们优先往左查询,并保证不越过区间之外,如果查询到满足条件的,我们不再往后继续查询,否则往右查询。

      

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<bits/stdc++.h>
    #define LL long long
    #define lson rt<<1
    #define rson rt<<1|1
    using namespace std;
    const int maxx = 2e6+6;
    struct node{
      int l,r;
      int cnt;
    }tree[maxx<<2];
    int op[maxx],pos[maxx];
    vector<int>p;
    int cnt,ans;
    int get_pos(int x){
        return lower_bound(p.begin(),p.end(),x)-p.begin()+1;
    }
    void buildtree(int rt,int l,int r){
        tree[rt].l=l;
        tree[rt].r=r;
        if (l==r){
            tree[rt].cnt=r-l+1;
            return ;
        }
        int mid=(l+r)>>1;
        buildtree(lson,l,mid);
        buildtree(rson,mid+1,r);
        tree[rt].cnt=tree[lson].cnt+tree[rson].cnt;
    }
    void update(int rt,int pos){
        int l=tree[rt].l;
        int r=tree[rt].r;
        if (l==r){
            tree[rt].cnt=0;
            return ;
        }
        int mid=(l+r)>>1;
        if (pos<=mid){
            update(lson,pos);
        }else{
            update(rson,pos);
        }
        tree[rt].cnt=tree[lson].cnt+tree[rson].cnt;
    }
    int flag=0;
    void query(int rt,int ql,int qr){
        int l=tree[rt].l;
        int r=tree[rt].r;
        if(l==r){
            if(tree[rt].cnt){
             //   cout<<l<<" "<<r<<endl;
                flag=1;
                ans=p[l-1];
            }
            return ;
        }
        int mid=(l+r)>>1;
        if (!flag && ql<=mid && tree[lson].cnt){
            ///如果当前没有查到,并且左儿子的区间和询问区间有交集,并且左儿子区间有没有被消除的点
            ///这里注意,左区间和不为0不代表一定有,因为我们不知道左区间和询问区间的交集是否有
            query(lson,ql,qr);
        }
        if (!flag && tree[rson].cnt){
            query(rson,ql,qr);
        }
    }
    int main(){
       int n,q;
       while(~scanf("%d%d",&n,&q)){
          cnt=0;
          for(int i=1;i<=q;i++){
             scanf("%d%d",&op[i],&pos[i]);
             p.push_back(pos[i]);
             p.push_back(pos[i]+1);
          }
          sort(p.begin(),p.end());
          p.erase(unique(p.begin(),p.end()),p.end());
          int sz=p.size();
          buildtree(1,1,sz);
          for (int i=1;i<=q;i++){
              if (op[i]==1){
                 update(1,get_pos(pos[i]));
              }else{
                 flag=0;
                 query(1,get_pos(pos[i]),sz);
                 printf("%d
    ",ans);
              }
          }
       }
       return 0;
    }
  • 相关阅读:
    Python程序中的线程操作-concurrent模块
    python程序中的进程操作-进程间的数据共享
    有几个消费者就需要发送几次结束信号
    python进程池
    Python程序中的线程操作-concurrent模块
    Python程序中的线程操作-线程队列
    Python程序中的线程操作-守护线程
    进程操作-进程池
    进程池版socket并发聊天
    使用多进程请求多个url来减少网络等待浪费的时间
  • 原文地址:https://www.cnblogs.com/bluefly-hrbust/p/11508332.html
Copyright © 2020-2023  润新知