二逼平衡树 题解报告
先占个坑
#include<bits/stdc++.h>
using namespace std;
const int N=2e4+2;
int n,m,cnt,num,a[N<<1],h[N<<2],tot,n1,n2,x,y,z;
struct node{
int fg;
int l,r,k;
int pos,val;
}s[N];
int w[N<<8],rt[N<<8],ls[N<<8],rs[N<<8];
int t1[N<<3],t2[N<<3];
int lowbit(int x){
return x&(-x);
}
void add(int x,int y,int l,int r,int val){
w[x]+=val;
if(l==r) return ;
int mid=(l+r)>>1;
if(y<=mid){
if(!ls[x]) ls[x]=++tot;
add(ls[x],y,l,mid,val);
}else{
if(!rs[x]) rs[x]=++tot;
add(rs[x],y,mid+1,r,val);
}
}
void update(int id,int val){
int x=lower_bound(h+1,h+1+num,a[id])-h;
for(int i=id;i<=n;i+=lowbit(i)){
if(!rt[i]) rt[i]=++tot;
add(rt[i],x,1,num,val);
}
}
int kth(int l,int r,int k){
if(l==r) return l;
int sum=0,mid=(l+r)>>1;
for(int i=1;i<=n1;i++){
sum+=w[ls[t1[i]]];
}
for(int i=1;i<=n2;i++){
sum-=w[ls[t2[i]]];
}
if(sum>=k){
for(int i=1;i<=n1;i++){
t1[i]=ls[t1[i]];
}
for(int i=1;i<=n2;i++){
t2[i]=ls[t2[i]];
}
return kth(l,mid,k);
}else{
for(int i=1;i<=n1;i++){
t1[i]=rs[t1[i]];
}
for(int i=1;i<=n2;i++){
t2[i]=rs[t2[i]];
}
return kth(mid+1,r,k-sum);
}
}
int query(int l,int r,int k){
n1=n2=0;
for(int i=r;i>0;i-=lowbit(i)){
t1[++n1]=rt[i];
}
for(int i=l-1;i>0;i-=lowbit(i)){
t2[++n2]=rt[i];
}
return kth(1,num,k);
}
void change(int x){
int id=s[x].pos;
update(id,-1);
a[id]=s[x].val;
update(id,1);
}
int update2(int l,int r,int k){
if(l==r) return 0;
int sum=0,mid=(l+r)>>1;
for(int i=1;i<=n1;i++){
sum+=w[ls[t1[i]]];
}
for(int i=1;i<=n2;i++){
sum-=w[ls[t2[i]]];
}
if(mid>=k){
for(int i=1;i<=n1;i++){
t1[i]=ls[t1[i]];
}
for(int i=1;i<=n2;i++){
t2[i]=ls[t2[i]];
}
return update2(l,mid,k);
}else{
for(int i=1;i<=n1;i++){
t1[i]=rs[t1[i]];
}
for(int i=1;i<=n2;i++){
t2[i]=rs[t2[i]];
}
return update2(mid+1,r,k)+sum;
}
}
int update1(int l,int r,int kk){
int k=lower_bound(h+1,h+1+num,kk)-h;
n1=n2=0;
for(int i=r;i>0;i-=lowbit(i)){
t1[++n1]=rt[i];
}
for(int i=l-1;i>0;i-=lowbit(i)){
t2[++n2]=rt[i];
}
return update2(1,num,k);
}
int update4(int l,int r,int k){
int id=update1(l,r,k);
return query(l,r,id);
}
int update7(int l,int r,int k){
if(l==r) return 0;
int sum=0,mid=(l+r)>>1;
for(int i=1;i<=n1;i++){
sum+=w[ls[t1[i]]];
}
for(int i=1;i<=n2;i++){
sum-=w[ls[t2[i]]];
}
if(k<mid){
for(int i=1;i<=n1;i++){
t1[i]=ls[t1[i]];
}
for(int i=1;i<=n2;i++){
t2[i]=ls[t2[i]];
}
return update7(l,mid,k);
}else{
for(int i=1;i<=n1;i++){
t1[i]=rs[t1[i]];
}
for(int i=1;i<=n2;i++){
t2[i]=rs[t2[i]];
}
return update7(mid+1,r,k)+sum;
}
}
int update6(int l,int r,int kk){
int k=lower_bound(h+1,h+1+num,kk)-h;
n1=n2=0;
for(int i=r;i>0;i-=lowbit(i)){
t1[++n1]=rt[i];
}
for(int i=l-1;i>0;i-=lowbit(i)){
t2[++n2]=rt[i];
}
return update7(1,num,k);
}
int update5(int l,int r,int k){
int id=update6(l,r,k)+1;
return query(l,r,id);
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
h[++cnt]=a[i];
}
for(int i=1;i<=m;i++){
int fg,pos,l,r,k;
scanf("%d",&fg);
if(fg==3){
scanf("%d%d",&pos,&k);
h[++cnt]=k;
s[i].fg=fg;
s[i].pos=pos;
s[i].val=k;
}else{
scanf("%d%d%d",&l,&r,&k);
s[i].fg=fg;
s[i].l=l;
s[i].r=r;
s[i].k=k;
if(fg!=2) h[++cnt]=k;
}
}
sort(h+1,h+1+cnt);
num=unique(h+1,h+1+cnt)-h-1;
for(int i=1;i<=n;i++){
update(i,1);
}
for(int i=1;i<=m;i++){
int fg=s[i].fg;
if(fg==1) printf("%d\n",update1(s[i].l,s[i].r,s[i].k)+1);
if(fg==2) printf("%d\n",h[query(s[i].l,s[i].r,s[i].k)]);
if(fg==3) change(i);
if(fg==4) printf("%d\n",h[update4(s[i].l,s[i].r,s[i].k)]);
if(fg==5) printf("%d\n",h[update5(s[i].l,s[i].r,s[i].k)]);
}
return 0;
}
本文作者:Yvette的博客
本文链接:https://www.cnblogs.com/yvette1217/p/16353248.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步