主席树就是所谓可持久化线段树。目前只会打区间k值操作。
那么带修改的呢?因为主席树目的上也是搞前缀和,所以类比数组操作,套一个树状数组就可以了。
谨以此纪念此类型树套树入门
#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define pos(i,a,b) for(int i=(a);i<=(b);i++) #define N 51000 #include<vector> #include<algorithm> int lowbit(int x){ return x&(-x); } int tes; int n,m,sz,len; int a[N],root[N]; vector<int> b; int find(int x){ return lower_bound(b.begin(),b.end(),x)-b.begin()+1; } struct haha{ int lc,rc,sum; }tree[N*100]; int ans; struct xixi{ int x,y,k; }cun[N]; int downx[N],downy[N]; void init(){ memset(tree,0,sizeof(tree)); memset(cun,0,sizeof(cun)); b.clear(); pos(i,0,n+100) a[i]=root[i]=0; sz=0;ans=0;len=0; } void update(int &rt,int pos,int l,int r,int num){ if(!rt) rt=++sz; if(l==r){ tree[rt].sum+=num;return; } int mid=(l+r)>>1; if(pos<=mid) update(tree[rt].lc,pos,l,mid,num); else update(tree[rt].rc,pos,mid+1,r,num); tree[rt].sum=tree[tree[rt].lc].sum+tree[tree[rt].rc].sum; } void add(int x,int pos,int num){ while(x<=n){ update(root[x],pos,1,len,num); x+=lowbit(x); } } int query(int l,int r,int k){ if(l==r) return l; int mid=(l+r)>>1; int sumx(0),sumy(0),t(0); pos(i,1,downx[0]) sumx+=tree[tree[downx[i]].lc].sum; pos(i,1,downy[0]) sumy+=tree[tree[downy[i]].lc].sum; t=sumy-sumx; if(t>=k){ pos(i,1,downx[0]) downx[i]=tree[downx[i]].lc; pos(i,1,downy[0]) downy[i]=tree[downy[i]].lc; return query(l,mid,k); } else{ pos(i,1,downx[0]) downx[i]=tree[downx[i]].rc; pos(i,1,downy[0]) downy[i]=tree[downy[i]].rc; return query(mid+1,r,k-t); } } int Query(int x,int y,int k){ downx[0]=downy[0]=0; int tx=x,ty=y; while(tx>0){ downx[++downx[0]]=root[tx];tx-=lowbit(tx); } while(ty>0){ downy[++downy[0]]=root[ty];ty-=lowbit(ty); } return query(1,len,k); } int main(){ scanf("%d",&tes); while(tes--){ scanf("%d%d",&n,&m); init(); pos(i,1,n) scanf("%d",&a[i]),b.push_back(a[i]); pos(i,1,m){ char c;cin>>c; int x,y,k;scanf("%d%d",&x,&y); cun[i].x=x;cun[i].y=y; if(c==‘Q‘){ scanf("%d",&k);cun[i].k=k; } else{ b.push_back(y); } } sort(b.begin(),b.end()); b.erase(unique(b.begin(),b.end()),b.end()); len=b.size(); pos(i,1,n){ add(i,find(a[i]),1); } pos(i,1,m){ int x=cun[i].x,y=cun[i].y,k=cun[i].k; if(k){ ans=Query(x-1,y,k); ans=b[ans-1]; printf("%d\n",ans); } else{ add(x,find(a[x]),-1); add(x,find(y),1); a[x]=y; } } } return 0; }
时间: 2024-10-25 13:33:12