标签:主席树 -- lowbit algorithm amp ios erase lower query
主席树就是所谓可持久化线段树。目前只会打区间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;
}
标签:主席树 -- lowbit algorithm amp ios erase lower query
原文地址:http://www.cnblogs.com/Hallmeow/p/7953784.html