啥 第一道树套树
题意 给你n个数 两种操作 一种操作查询L-R 第k大的树 静态主席树经典问题 第二种操作 把a[i] 改为t
做法 我们知道如果你想建主席树 然后暴力维护 暴力跑 时间复杂度讲会是 m*n*logn 就TLE了 况且你建主席树太多还会MLE
那么怎么做到修改呢?首先我们要知道一定要把后来修改的值也放进去离散化的数组里面 然后还是正常建主席树 唯一的区别是 我们考虑改一个值 实际上就是在那个树的那个值上-1 并且新的值+1 这就很像树状数组 然后ul ur数组是随着主席树下移用的 结构体的带修主席树还不会敲 所以和之前的代码有一点点不同 思路大抵相同 看看吧
#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 6e4+5;
const int MAX_M = 1e4+5;
int T[MAX_N],S[MAX_N],L[MAX_N*32],R[MAX_N*32],sum[MAX_N*32];
vector<int > vt;
int getid(int x){return lower_bound(vt.begin(),vt.end(),x)-vt.begin()+1;}
int arr[MAX_N],ul[MAX_N],ur[MAX_N];
int n,m,cnt,num;
struct node{int l,r,k;bool flag;}Q[MAX_M];
void build(int &rt,int l,int r)
{
rt = ++cnt,sum[rt] = 0;
if(l==r) return;
int mid = (l+r)>>1;
build(L[rt],l,mid);
build(R[rt],mid+1,r);
}
void update(int l,int r,int &x,int y,int pos,int val)
{
x = ++cnt,L[x] = L[y],R[x] = R[y],sum[x] = sum[y] + val;
if(l==r) return ;
int mid = (l+r)>>1;
if(pos<=mid) update(l,mid,L[x],L[y],pos,val);
else update(mid+1,r,R[x],R[y],pos,val);
}
int lowbit(int x){return x&(-x);}
void add(int x,int val)
{
int res = getid(arr[x]);
while(x<=n)
{
update(1,num,S[x],S[x],res,val);
x+=lowbit(x);
}
}
int Sum(int x,bool flag)
{
int res = 0;
while(x)
{
if(flag) res += sum[L[ur[x]]];
else res += sum[L[ul[x]]];
x-=lowbit(x);
}
return res;
}
int query(int l,int r,int x,int y,int tx,int ty,int k)
{
if(l==r) return l;
int mid = (l+r)>>1;
int res = Sum(y,true) - Sum(x,false) + sum[L[ty]] - sum[L[tx]];
if(k<=res)
{
for(int i = y;i;i-=lowbit(i)) ur[i] = L[ur[i]];
for(int i = x;i;i-=lowbit(i)) ul[i] = L[ul[i]];
return query(l,mid,x,y,L[tx],L[ty],k);
}
else
{
for(int i = y;i;i-=lowbit(i)) ur[i] = R[ur[i]];
for(int i = x;i;i-=lowbit(i)) ul[i] = R[ul[i]];
return query(mid+1,r,x,y,R[tx],R[ty],k-res);
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
vector<int > vt_;
swap(vt,vt_);
char str[5];
num = 0;
scanf("%d%d",&n,&m);
for(int i = 1;i<=n;++i) scanf("%d",&arr[i]),vt.push_back(arr[i]);
for(int i = 1;i<=m;++i)
{
scanf("%s",str);
if(str[0]=='Q')
{
scanf("%d%d%d",&Q[i].l,&Q[i].r,&Q[i].k);
Q[i].flag = true;
}
else
{
scanf("%d%d",&Q[i].l,&Q[i].r);
Q[i].flag = false;
vt.push_back(Q[i].r);
}
}
sort(vt.begin(),vt.end()),vt.erase(unique(vt.begin(),vt.end()),vt.end());
int tmp = vt.size();
num = tmp;
cnt = 0;
build(T[0],1,num);
for(int i = 1;i<=n;++i) update(1,num,T[i],T[i-1],getid(arr[i]),1);
for(int i = 1;i<=n;++i) S[i] = T[0];
for(int i = 1;i<=m;++i)
{
if(Q[i].flag)
{
for(int j = Q[i].r;j;j-=lowbit(j)) ur[j] = S[j];
for(int j = Q[i].l-1;j;j-=lowbit(j)) ul[j] = S[j];
printf("%d\n",vt[query(1,num,Q[i].l-1,Q[i].r,T[Q[i].l-1],T[Q[i].r],Q[i].k)-1]);
}
else
{
add(Q[i].l,-1);
arr[Q[i].l] = Q[i].r;
add(Q[i].l,1);
}
}
}
return 0;
}