所谓带修主席树,就是用树状数组的方法维护主席树的前缀和
思路
带修主席树的板子
注意数据范围显然要离散化即可
代码
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct Node{
int sz,lson,rson;
}PT[100100*400];
struct Q{
char c;
int l,r,x,val;
}opt[100100];
const int MAXV = 1e9+10;
int Nodecnt,lcnt,rcnt,root[100100],n,m,a[100100],num[200100],nx;
int lroot[100100],rroot[100100];
int lowbit(int x){
return x&(-x);
}
void update(int L,int R,int &o,int c,int x){
PT[++Nodecnt]=PT[o];
o=Nodecnt;
PT[o].sz+=c;
if(L==R)
return;
int mid=(L+R)>>1;
if(x<=mid)
update(L,mid,PT[o].lson,c,x);
else
update(mid+1,R,PT[o].rson,c,x);
}
int query(int l,int r,int L,int R,int k){
lcnt=0,rcnt=0;
for(int i=L-1;i;i-=lowbit(i))
lroot[++lcnt]=root[i];
for(int i=R;i;i-=lowbit(i))
rroot[++rcnt]=root[i];
while(l<=r){
if(l==r)
return l;
int lch=0,mid=(l+r)>>1;
for(int i=1;i<=rcnt;i++)
lch+=PT[PT[rroot[i]].lson].sz;
for(int i=1;i<=lcnt;i++)
lch-=PT[PT[lroot[i]].lson].sz;
if(k>lch){//to right
for(int i=1;i<=rcnt;i++)
rroot[i]=PT[rroot[i]].rson;
for(int i=1;i<=lcnt;i++)
lroot[i]=PT[lroot[i]].rson;
k-=lch;
l=mid+1;
}
else{
for(int i=1;i<=rcnt;i++)
rroot[i]=PT[rroot[i]].lson;
for(int i=1;i<=lcnt;i++)
lroot[i]=PT[lroot[i]].lson;
r=mid;
}
}
}
void set(int pos,int x,int c){//x-c
while(pos<=n){
update(1,nx,root[pos],c,x);
pos+=lowbit(pos);
}
}
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
num[++nx]=a[i];
}
for(int i=1;i<=m;i++){
char c=getchar();
while(c!='Q'&&c!='C')
c=getchar();
if(c=='Q'){
opt[i].c='Q';
scanf("%d %d %d",&opt[i].l,&opt[i].r,&opt[i].val);
}
else{
opt[i].c='C';
scanf("%d %d",&opt[i].val,&opt[i].x);
num[++nx]=opt[i].x;
}
}
sort(num+1,num+nx+1);
nx=unique(num+1,num+nx+1)-num-1;
for(int i=1;i<=n;i++)
a[i]=lower_bound(num+1,num+nx+1,a[i])-num;
for(int i=1;i<=m;i++)
if(opt[i].c=='C')
opt[i].x=lower_bound(num+1,num+nx+1,opt[i].x)-num;
for(int i=1;i<=n;i++)
set(i,a[i],1);
for(int i=1;i<=m;i++){
if(opt[i].c=='Q'){
printf("%d\n",num[query(1,nx,opt[i].l,opt[i].r,opt[i].val)]);
}
else{
set(opt[i].val,a[opt[i].val],-1);
set(opt[i].val,opt[i].x,1);
a[opt[i].val]=opt[i].x;
}
}
return 0;
}
原文地址:https://www.cnblogs.com/dreagonm/p/10105213.html
时间: 2024-10-05 21:40:57