裸的带修改主席树,套个树状数组。
所以也勉强算是个树套树,嘛不过树套树也能过就是了。
具体来说,就是每个bit节点都是一颗主席树。
由于bit支持前缀和的修改操作,而主席树是一种前缀结构,所以是可以套的。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int maxn=2e6+5+2e5+5;
const int M=2e6+5+2e5+5;
typedef long long ll;
int v[maxn];
int a[maxn],b[maxn],c[maxn],K[maxn];
int N;
int l,r,L[30],R[30];
bool flag[maxn];
int hash[maxn];
int num[maxn],cnt,op;
int n,m,sz,t,ans,root[maxn],ls[M],rs[M];
int sum[M];
inline int lowbit(int x)
{
return x&(-x);
}
void update(int last,int &x,int l,int r,int w,int v)
{
x=++sz;
sum[x]=sum[last]+v;
int mid=(l+r)>>1;
ls[x]=ls[last],rs[x]=rs[last];
if (l==r)return;
if (w<=mid)update(ls[last],ls[x],l,mid,w,v);
else update(rs[last],rs[x],mid+1,r,w,v);
}
inline int query(int l1,int r1,int k)
{
if (l1==r1)return l1;
int i,suml=0,sumr=0;
fo(i,1,l)suml+=sum[ls[L[i]]];
fo(i,1,r)sumr+=sum[ls[R[i]]];
int mid=(l1+r1)>>1;
if (sumr-suml>=k)
{
fo(i,1,l)L[i]=ls[L[i]];
fo(i,1,r)R[i]=ls[R[i]];
return query(l1,mid,k);
}
else
{
fo(i,1,l)L[i]=rs[L[i]];
fo(i,1,r)R[i]=rs[R[i]];
return query(mid+1,r1,k-(sumr-suml));
}
}
inline int find(int x)
{
int l=1,r=N,mid;
while (l<=r)
{
mid=(l+r)>>1;
if (x>hash[mid])l=mid+1;
else r=mid-1;
}
return l;
}
int main()
{
scanf("%d%d",&n,&m);
char s[3];
fo(i,1,n)
{
scanf("%d",&v[i]);
num[++cnt]=v[i];
}
fo(i,1,m)
{
scanf("%s",s);
scanf("%d%d",&a[i],&b[i]);
if (s[0]=='Q')
{
scanf("%d",&K[i]);
flag[i]=true;
}
else num[++cnt]=b[i];
}
sort(num+1,num+1+cnt);
hash[++N]=num[1];
fo(i,2,cnt)
if (num[i]!=num[i-1])hash[++N]=num[i];
fo(i,1,n)
{
int t=find(v[i]);
for(int j=i;j<=n;j+=lowbit(j))
update(root[j],root[j],1,N,t,1);
}
fo(i,1,m)
{
if (flag[i])
{
l=0,r=0;
a[i]--;
for(int j=a[i];j>0;j-=lowbit(j))
L[++l]=root[j];
for(int j=b[i];j>0;j-=lowbit(j))
R[++r]=root[j];
printf("%d\n",hash[query(1,N,K[i])]);
}
else
{
int t=find(v[a[i]]);
for(int j=a[i];j<=n;j+=lowbit(j))
update(root[j],root[j],1,N,t,-1);
v[a[i]]=b[i];
t=find(b[i]);
for(int j=a[i];j<=n;j+=lowbit(j))
update(root[j],root[j],1,N,t,1);
}
}
}