• P3380 【模板】二逼平衡树(树套树)


    题面

    https://www.luogu.org/problem/P3380

    题解

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #define ri register int
    using namespace std;
    struct node{
      vector<int> a;
      void insert(int x){
        a.insert(upper_bound(a.begin(),a.end(),x),x);
      }
      void change(int old,int now) {
        a.erase(lower_bound(a.begin(),a.end(),old));
        a.insert(upper_bound(a.begin(),a.end(),now),now);
      }
      int find(int now){
        if ((*a.begin())>=now) return 0;
        return lower_bound(a.begin(),a.end(),now)-a.begin();
      }
    } ff[50050];
    int a[50050];
    int n,m;
    
    int lowbit(int x){
      return x&(-x);
    }
    
    int findbyrank(int l,int r,int k){
      int lb=-1e8,rb=1e8,mid,ans=-1;
      while (lb<=rb) {
        mid=(lb+rb)/2;
        int s1=0,s2=0;
        for (ri j=r;j>=1;j-=lowbit(j)) s1+=ff[j].find(mid);
        for (ri j=l-1;j>=1;j-=lowbit(j)) s2+=ff[j].find(mid);
        if (s1-s2+1<=k) lb=mid+1,ans=mid; else rb=mid-1;
      }
      return ans;
    }
    
    int findpre(int l,int r,int k){
      int ans=-2147483647;
      for (ri i=r;i>=l;) if (i-lowbit(i)+1>=l) {
        if ((*ff[i].a.begin())>=k) {i-=lowbit(i); continue;}
        else ans=max(*(--lower_bound(ff[i].a.begin(),ff[i].a.end(),k)),ans);
        i-=lowbit(i);
      }
      else {
        if (a[i]<k) ans=max(a[i],ans);
        i--;
      }
      return ans;
    }
    
    int findsuc(int l,int r,int k){
      int ans=2147483647;
      for (ri i=r;i>=l;) if (i-lowbit(i)+1>=l) {
        if (ff[i].a[ff[i].a.size()-1]<=k) {i-=lowbit(i);continue;}
            else ans=min(*(upper_bound(ff[i].a.begin(),ff[i].a.end(),k)),ans);
        i-=lowbit(i);
      }
      else {
        if (a[i]>k) ans=min(a[i],ans);
        i--;
      }
      return ans;
    }
    
    int main() {
      int x,opt,l,r,k,pos;
      scanf("%d %d",&n,&m);
      for (ri i=1;i<=n;i++) {
        scanf("%d",&x);
        a[i]=x;
        for (ri j=i;j<=n;j+=lowbit(j)) ff[j].insert(x);
      }
      for (ri i=1;i<=m;i++) {
        scanf("%d",&opt);
        if (opt==1) {
          scanf("%d %d %d",&l,&r,&k);
          int s1=0,s2=0;
          for (ri j=r;j>=1;j-=lowbit(j)) s1+=ff[j].find(k);
          for (ri j=l-1;j>=1;j-=lowbit(j)) s2+=ff[j].find(k);
          printf("%d
    ",s1-s2+1);
        }
        if (opt==2) {
          scanf("%d %d %d",&l,&r,&k);
          printf("%d
    ",findbyrank(l,r,k));
        }
        if (opt==3) {
          scanf("%d %d",&pos,&k);
          for (ri j=pos;j<=n;j+=lowbit(j)) ff[j].change(a[pos],k);
          a[pos]=k;
        }
        if (opt==4) {
          scanf("%d %d %d",&l,&r,&k);
          printf("%d
    ",findpre(l,r,k));
        }
        if (opt==5) {
          scanf("%d %d %d",&l,&r,&k);
          printf("%d
    ",findsuc(l,r,k));
        }
      }
    }
  • 相关阅读:
    最大正数pascal程序
    部落卫队pascal解题程序
    使用递归和非递归遍历二叉树
    机器学习 Numpy库入门
    C++ 多态性和虚函数
    C++ 利用栈解决运算问题
    C++ 字符串分割
    C++继承与派生
    机器学习基础
    C++ 输出文件编码控制
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11427248.html
Copyright © 2020-2023  润新知