zoukankan      html  css  js  c++  java
  • P3380 【模板】二逼平衡树(树套树)

    洛谷传送门

    树套树板子

    本来打算写大佬口胡的树状数组套主席树的

    然而我根本写不来

    网上随便抄了一篇线段树套Treap的

    跑的飞慢

      1 // luogu-judger-enable-o2
      2 //minamoto
      3 #include<bits/stdc++.h>
      4 #define inf 2147483647
      5 using namespace std;
      6 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
      7 char buf[1<<21],*p1=buf,*p2=buf;
      8 inline int read(){
      9     #define num ch-'0'
     10     char ch;bool flag=0;int res;
     11     while(!isdigit(ch=getc()))
     12     (ch=='-')&&(flag=true);
     13     for(res=num;isdigit(ch=getc());res=res*10+num);
     14     (flag)&&(res=-res);
     15     #undef num
     16     return res;
     17 }
     18 char sr[1<<21],z[20];int C=-1,Z;
     19 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
     20 inline void print(int x){
     21     if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
     22     while(z[++Z]=x%10+48,x/=10);
     23     while(sr[++C]=z[Z],--Z);sr[++C]='
    ';
     24 }
     25 const int N=50005;
     26 int val[N],n,m,a,b,c;
     27 struct node{
     28     node* ch[2];
     29     int rank,val,size;
     30     node (int  x){val=x,rank=rand(),size=1,ch[0]=ch[1]=NULL;}
     31     void up(){
     32         size=1;
     33         if(ch[0]) size+=ch[0]->size;
     34         if(ch[1]) size+=ch[1]->size;
     35     }
     36 };
     37 inline int s(node* p){return p?p->size:0;}
     38 node* rt[N*4];
     39 void rotate(node* &p,int d){
     40     node* k=p->ch[d^1];p->ch[d^1]=k->ch[d],k->ch[d]=p;
     41     p->up(),k->up(),p=k;
     42 }
     43 void insert(node* &p,int val){
     44     if(p==NULL) return (void)(p=new node(val));
     45     if(val<p->val){
     46         insert(p->ch[0],val);
     47         if(p->ch[0]->rank>p->rank) rotate(p,1);
     48     }
     49     else{
     50         insert(p->ch[1],val);
     51         if(p->ch[1]->rank>p->rank) rotate(p,0);
     52     }
     53     p->up();
     54 }
     55 void build(int l,int r,int p){
     56     for(int i=l;i<=r;++i) insert(rt[p],val[i]);
     57     if(l==r) return;
     58     int mid=(l+r)>>1;
     59     build(l,mid,p<<1);
     60     build(mid+1,r,p<<1|1);
     61 }
     62 void remove(node* &p,int val){
     63     if(p==NULL) return;
     64     if(val==p->val){
     65         if(p->ch[0]&&p->ch[1]){
     66             int d=(p->ch[0]->rank > p->ch[1]->rank);
     67             rotate(p,d),remove(p->ch[d],val);
     68         }
     69         else{
     70             node* u=(p->ch[0]==NULL)?p->ch[1]:p->ch[0];
     71             delete p;
     72             p=u;
     73         }
     74     }
     75     else if(val<p->val) remove(p->ch[0],val);
     76     else remove(p->ch[1],val);
     77     if(p) p->up();
     78 }
     79 inline int find_rank(node* p,int val){
     80     int sum=0;
     81     while(p){
     82         (val>p->val)?(sum+=s(p->ch[0])+1,p=p->ch[1]):(p=p->ch[0]);
     83     }
     84     return sum;
     85 }
     86 int tree_rank(int l,int r,int p,int val){
     87     if(a<=l&&b>=r) return find_rank(rt[p],val);
     88     int mid=(l+r)>>1,res=0;
     89     if(a<=mid) res+=tree_rank(l,mid,p<<1,val);
     90     if(b>mid) res+=tree_rank(mid+1,r,p<<1|1,val);
     91     return res;
     92 }
     93 inline int divide_rank(int val){
     94     int l=0,r=1e8;
     95     while(l<=r){
     96         int mid=(l+r)>>1;
     97         int check=tree_rank(1,n,1,mid)+1;
     98         if(check<=val) l=mid+1;
     99         else r=mid-1;
    100     }
    101     return r;
    102 }
    103 inline int Pre(int l,int r,int val){
    104     int tmp=tree_rank(1,n,1,val);
    105     int res=divide_rank(tmp);
    106     return res==-1?-inf:res;
    107 }
    108 inline int re(int l,int r,int val){
    109     int tmp=tree_rank(1,n,1,val+1)+1;
    110     int res=divide_rank(tmp);
    111     return res==1e8?inf:res;
    112 }
    113 void change(int l,int r,int p,int pos,int Pre,int now){
    114     remove(rt[p],Pre);
    115     insert(rt[p],now);
    116     if(l==r) return;
    117     int mid=(l+r)>>1;
    118     if(pos<=mid) change(l,mid,p<<1,pos,Pre,now);
    119     else change(mid+1,r,p<<1|1,pos,Pre,now);
    120 }
    121 int main(){
    122     //freopen("testdata.in","r",stdin);
    123     //freopen("check.out","w",stdout);
    124     n=read(),m=read();
    125     for(int i=1;i<=n;++i) val[i]=read();
    126     build(1,n,1);
    127     while(m--){
    128         int opt=read();
    129         switch(opt){
    130             case 1:{
    131                 a=read(),b=read(),c=read();
    132                 print(tree_rank(1,n,1,c)+1);
    133                 break;
    134             }
    135             case 2:{
    136                 a=read(),b=read(),c=read();
    137                 print(divide_rank(c));
    138                 break;
    139             }
    140             case 3:{
    141                 a=read(),b=read();
    142                 change(1,n,1,a,val[a],b),val[a]=b;
    143                 break;
    144             }
    145             case 4:{
    146                 a=read(),b=read(),c=read();
    147                 print(Pre(a,b,c));
    148                 break;
    149             }
    150             case 5:{
    151                 a=read(),b=read(),c=read();
    152                 print(re(a,b,c));
    153                 break;
    154             }
    155         }
    156     }
    157     Ot();
    158     return 0;
    159 }
  • 相关阅读:
    ORA-28000 帐户已被锁定问题处理
    德邦总管 修改oracle数据库用户密码的方法
    测试面试题目
    python 把一文件包含中文的字符写到另外文件乱码 UnicodeDecodeError: 'gbk' codec can't decode byte 0xac in position
    python version 2.7 required,which was not found in the registry
    ImportError: No module named dateutil.parser
    解决python2.x用urllib2证书验证错误, _create_unverified_context
    python多版本兼容性问题:当同时安装Python2和Python3后,如何兼容并切换
    MAC OS git客户端安装及操作
    Pycharm连接gitlab
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9439777.html
Copyright © 2011-2022 走看看