帶插入,修改的區間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 }