RT
为什么合并到叶子节点时,改成注释所写会出错?
#include <bits/stdc++.h>
#define int long long
using namespace std;
int read() {
int x=0,f=0; char ch=getchar();
while(!isdigit(ch)) f|=(ch=='-'),ch=getchar();
while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
return f?-x:x;
}
void put(int x) {
if(x<0) putchar('-'),x=-x;
if(x>=10) put(x/10);
putchar(x%10^48);
}
const int Maxn=2e5+10;
int n,m;
int root[Maxn],rt=1,cnt;
struct node {
int ls,rs,w;
}t[Maxn*100];
#define mid (l+r>>1)
inline void pushup(int x) {t[x].w=t[t[x].ls].w+t[t[x].rs].w;}
void modify(int &x,int l,int r,int p,int v) {
if(!x) x=++cnt;
if(l==r) return t[x].w+=v,void();
if(mid>=p) modify(t[x].ls,l,mid,p,v);
else modify(t[x].rs,mid+1,r,p,v);
pushup(x);
}
int merge(int p,int q) {
if(!q||!p) return p|q;
// if(!t[p].ls&&!t[p].rs) return t[p].w+=t[q].w,p;
t[p].w+=t[q].w;
t[p].ls=merge(t[p].ls,t[q].ls);
t[p].rs=merge(t[p].rs,t[q].rs);
// pushup(p);
return p;
}
void split(int &p,int &q,int l,int r,int L,int R) {
if(!q) return;
if(!p) p=++cnt;
if(l>=L&&r<=R) return swap(p,q),void();
if(mid>=L) split(t[p].ls,t[q].ls,l,mid,L,R);
if(mid<R) split(t[p].rs,t[q].rs,mid+1,r,L,R);
pushup(p),pushup(q);
}
int ask_size(int x,int l,int r,int L,int R) {
if(!x) return 0;
if(l>=L&&r<=R) return t[x].w;
int res=0;
if(mid>=L) res+=ask_size(t[x].ls,l,mid,L,R);
if(mid<R) res+=ask_size(t[x].rs,mid+1,r,L,R);
return res;
}
int ask_rank(int x,int l,int r,int k) {
if(t[x].w<k) return -1;
if(l==r) return l;
if(t[t[x].ls].w>=k) return ask_rank(t[x].ls,l,mid,k);
return ask_rank(t[x].rs,mid+1,r,k-t[t[x].ls].w);
}
signed main() {
// freopen("P5494_2.in","r",stdin);
// freopen("P5494.out","w",stdout);
n=read(),m=read();
for(int i=1;i<=n;++i) modify(root[rt],1,n,i,read());
while(m--) {
int op=read(),p,x,y,k;
switch (op) {
case 0:p=read(),x=read(),y=read(),split(root[++rt],root[p],1,n,x,y); break;
case 1:x=read(),y=read(),root[x]=merge(root[x],root[y]),root[y]=0; break;
case 2:p=read(),k=read(),x=read(),modify(root[p],1,n,x,k); break;
case 3:p=read(),x=read(),y=read(),put(ask_size(root[p],1,n,x,y)),putchar('\n'); break;
case 4:p=read(),k=read(),put(ask_rank(root[p],1,n,k)),putchar('\n'); break;
}
}
return 0;
}