【BZOJ3065】帶插入區間k小值

題意:

帶插入,修改的區間k小值在線查詢node

原序列長度<=35000,插入個數<=35000,修改個數<=70000,0<=權值<=70000ios

題解:

Orz vfleaking!!!ui

顯然這是道模板題,因爲強制在線因此不能總體二分水過了qwqspa

據說大量亂搞、分塊、塊狀鏈表、暴力+卡常都可過……我寫的hzwer樹套樹作法,就當鍛鍊碼力吧qwqcode

用替罪羊樹維護原序列,每一個點上維護一個權值線段樹,查詢時二分,碼碼碼便可;blog

線段樹點數過多因此要寫個內存池防止爆空間;內存

時間複雜度$O(qlog^3n)$string

其實也不難寫我就調了一下午+一夜而已it

代碼:

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<vector>
 5 #include<cstdio>
 6 #include<cmath>
 7 #include<queue>
 8 #define inf 2147483647
 9 #define eps 1e-9
 10 #define N 70000
 11 using namespace std;  12 typedef long long ll;  13 typedef double db;  14 const db alpha=0.75;  15 struct node{  16     int ls,rs,v;  17 }t[500001],tr[10000001];  18 int n,q,x,y,k,rt,rb,ans=0,cnt=0,rts[70001],id[70001];  19 char op[3];  20 vector<int>vec,dl,qu;  21 int newn(){  22     if(!vec.size())return ++cnt;  23     else{  24         int ret=vec[vec.size()-1];  25  vec.pop_back();  26         return ret;  27  }  28 }  29 bool bad(int u){  30     return tr[rts[u]].v*alpha<=max(tr[rts[t[u].ls]].v,tr[rts[t[u].rs]].v);  31 }  32 void rec(int &u){  33  vec.push_back(u);  34     if(tr[u].ls)rec(tr[u].ls);  35     if(tr[u].rs)rec(tr[u].rs);  36     tr[u].v=0;  37     u=0;  38 }  39 void del(int &u){  40  rec(rts[u]);  41     if(t[u].ls)del(t[u].ls);  42  dl.push_back(u);  43     if(t[u].rs)del(t[u].rs);  44     u=0;  45 }  46 void updata(int &u,int l,int r,int p,int x){  47     if(!u)u=newn();  48     if(l==r){  49         tr[u].v+=x;  50         return;  51  }  52     int mid=(l+r)/2;  53     if(p<=mid)updata(tr[u].ls,l,mid,p,x);  54     else updata(tr[u].rs,mid+1,r,p,x);  55     tr[u].v=tr[tr[u].ls].v+tr[tr[u].rs].v;  56     if(!tr[u].v)rec(u);  57 }  58 void build(int &u,int l,int r){  59     if(l>r)return;  60     if(l==r){  61         u=id[l];  62         updata(rts[u],0,N,t[u].v,1);  63         return;  64  }  65     int mid=(l+r)/2;  66     u=id[mid];  67     build(t[u].ls,l,mid-1);  68     build(t[u].rs,mid+1,r);  69     for(int i=l;i<=r;i++){  70         updata(rts[u],0,N,t[id[i]].v,1);  71  }  72 }  73 void rebuild(int &u){  74  del(u);  75     int sz=dl.size();  76     for(int i=0;i<sz;i++)id[i+1]=dl[i];  77     build(u,1,sz);  78  dl.clear();  79 }  80 int update(int u,int p,int x){  81     updata(rts[u],0,N,x,1);  82     int ret;  83     if(p==tr[rts[t[u].ls]].v+1){  84         ret=t[u].v;  85         t[u].v=x;  86     }else if(tr[rts[t[u].ls]].v>=p){  87         ret=update(t[u].ls,p,x);  88     }else ret=update(t[u].rs,p-tr[rts[t[u].ls]].v-1,x);  89     updata(rts[u],0,N,ret,-1);  90     return ret;  91 }  92 void ins(int &u,int p,int x){  93     if(!u){  94         u=++n;  95         updata(rts[u],0,N,x,1);  96         t[u].v=x;  97         return;  98  }  99     updata(rts[u],0,N,x,1); 100     if(tr[rts[t[u].ls]].v>=p){ 101  ins(t[u].ls,p,x); 102     }else ins(t[u].rs,p-tr[rts[t[u].ls]].v-1,x); 103     if(bad(u))rb=u; 104     else if(rb){ 105         if(rb==t[u].ls)rebuild(t[u].ls); 106         else rebuild(t[u].rs); 107         rb=0; 108  } 109 } 110 void query(int u,int l,int r){ 111     int L=tr[rts[t[u].ls]].v,R=tr[rts[u]].v; 112     if(l==1&&r==R){ 113  qu.push_back(rts[u]); 114         return; 115  } 116     if(l<=L+1&&r>=L+1)dl.push_back(t[u].v); 117     if(L>=r){ 118  query(t[u].ls,l,r); 119     }else if(l>L+1)query(t[u].rs,l-L-1,r-L-1); 120     else{ 121         if(l<=L)query(t[u].ls,l,L); 122         if(L+1<R)query(t[u].rs,1,r-L-1); 123  } 124 } 125 int Query(int l,int r,int k){ 126  query(rt,l,r); 127     int tmp,L=0,R=N,sz1=qu.size(),sz2=dl.size(); 128     while(L<R){ 129         int mid=(L+R)/2; 130         tmp=0; 131         for(int i=0;i<sz1;i++){ 132             tmp+=tr[tr[qu[i]].ls].v; 133  } 134         for(int i=0;i<sz2;i++){ 135             if(L<=dl[i]&&dl[i]<=mid)tmp++; 136  } 137         if(tmp>k){ 138             for(int i=0;i<sz1;i++)qu[i]=tr[qu[i]].ls; 139             R=mid; 140         }else{ 141             for(int i=0;i<sz1;i++)qu[i]=tr[qu[i]].rs; 142             L=mid+1; 143             k-=tmp; 144  } 145  } 146  qu.clear(); 147  dl.clear(); 148     return L; 149 } 150 int main(){ 151     scanf("%d",&n); 152     for(int i=1;i<=n;i++){ 153         scanf("%d",&t[i].v); 154         id[i]=i; 155  } 156     build(rt,1,n); 157     scanf("%d",&q); 158     while(q--){ 159         //for(int i=1;i<=n;i++)printf("%d ",rts[i]); 160         //puts("");
161         scanf("%s",op); 162         if(op[0]=='M'){ 163             scanf("%d%d",&x,&k); 164             x^=ans,k^=ans; 165  update(rt,x,k); 166         }else if(op[0]=='I'){ 167             scanf("%d%d",&x,&k); 168             x^=ans,k^=ans; 169             rb=0; 170             ins(rt,x-1,k); 171             if(rb)rb=0,rebuild(rt); 172         }else{ 173             scanf("%d%d%d",&x,&y,&k); 174             x^=ans,y^=ans,k^=ans; 175             printf("%d\n",ans=Query(x,y,k-1)); 176  } 177  } 178     return 0; 179 } 
相關文章
相關標籤/搜索