题解:
替罪羊树
(讲道理昨天讲课我一点都听不懂)
alpha取到0.75比较好(当然啦可能其他的更好)
每当不满足条件的时候就重构
代码:
#include<bits/stdc++.h> using namespace std; const double alpha=0.75; const int N=10000005,M=100005; int tmp,n,m,sz,lastans,root,v[M],dfn[M],rt[M],ls[M],rs[M]; struct seg{int l,r,sum;}a[N]; vector<int> rec,t,p; inline int newnode() { if (!rec.size())return ++sz; else { int k=rec.back(); rec.pop_back(); return k; } } void reclaim(int &x) { if (!x)return; rec.push_back(x); reclaim(a[x].l); reclaim(a[x].r); a[x].sum=0;x=0; } void insert(int &k,int l,int r,int val,int f) { if (!k)k=newnode(); if (l==r) { a[k].sum+=f; return; } int mid=(l+r)>>1; if (val<=mid)insert(a[k].l,l,mid,val,f); else insert(a[k].r,mid+1,r,val,f); a[k].sum=a[a[k].l].sum+a[a[k].r].sum; if (!a[k].sum)reclaim(k); } void build(int &k,int l,int r) { if (l>r)return; if (l==r) { k=dfn[l]; insert(rt[k],0,70000,v[k],1); return; } int mid=(l+r)>>1; k=dfn[mid]; build(ls[k],l,mid-1); build(rs[k],mid+1,r); for (int i=l;i<=r;i++)insert(rt[k],0,70000,v[dfn[i]],1); } void del(int &x) { if(!x)return; reclaim(rt[x]); del(ls[x]); p.push_back(x); del(rs[x]); x=0; } void rebuild(int &x) { del(x); int s1=p.size(); for (int i=1;i<=s1;i++)dfn[i]=p[i-1]; build(x,1,s1); p.clear(); } int modify(int k,int x,int val) { insert(rt[k],0,70000,val,1); int t,L=a[rt[ls[k]]].sum; if (L+1==x){t=v[k];v[k]=val;} else if (L>=x)t=modify(ls[k],x,val); else t=modify(rs[k],x-L-1,val); insert(rt[k],0,70000,t,-1); return t; } void query(int k,int l,int r) { int L=a[rt[ls[k]]].sum,R=a[rt[k]].sum; if (l==1&&r==R){t.push_back(rt[k]);return;} if (l<=L+1&&r>=L+1)p.push_back(v[k]); if (r<=L)query(ls[k],l,r); else if (l>L+1)query(rs[k],l-L-1,r-L-1); else { if (l<=L)query(ls[k],l,L); if (R>L+1)query(rs[k],1,r-L-1); } } int solve_query(int L,int R,int K) { query(root,L,R); K--; int l=0,r=70000,s1=t.size(),s2=p.size(); while(l<r) { int mid=(l+r)>>1,sum=0; for (int i=0;i<s1;i++)sum+=a[a[t[i]].l].sum; for (int i=0;i<s2;i++) if(p[i]>=l&&p[i]<=mid)sum++; if (K<sum) { for (int i=0;i<s1;i++)t[i]=a[t[i]].l; r=mid; } else { for (int i=0;i<s1;i++)t[i]=a[t[i]].r; l=mid+1;K-=sum; } } t.clear();p.clear(); return l; } void insert(int &k,int x,int val) { if (!k) { k=++n; insert(rt[k],0,70000,val,1); v[k]=val; return; } insert(rt[k],0,70000,val,1); int L=a[rt[ls[k]]].sum; if (L>=x)insert(ls[k],x,val); else insert(rs[k],x-L-1,val); if (a[rt[k]].sum*alpha>max(a[rt[ls[k]]].sum,a[rt[rs[k]]].sum)) { if (tmp) { if (ls[k]==tmp)rebuild(ls[k]); else rebuild(rs[k]); tmp=0; } } else tmp=k; } int main() { scanf("%d",&n); for (int i=1;i<=n;i++)scanf("%d",&v[i]); for (int i=1;i<=n;i++)dfn[i]=i; build(root,1,n); scanf("%d",&m); char s[2]; int x,y,k; while (m--) { scanf("%s",&s); scanf("%d%d",&x,&y); x^=lastans;y^=lastans; if (s[0]=='Q') { scanf("%d",&k); k^=lastans; lastans=solve_query(x,y,k); printf("%d\n",lastans); } if (s[0]=='M')modify(root,x,y); if (s[0]=='I') { tmp=0; insert(root,x-1,y); if (tmp) { tmp=0; rebuild(root); } } } }