rt,只过了后面两个Hack
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=5e6+5;
struct node{
int ls,rs,sum;
};
node tr[N];
int cnt,rub[N],root[N],tot;
void del(int &o) {
tr[o]=(node){0,0,0};
rub[++cnt]=o; o=0;
}
int get_new() {
return cnt?rub[cnt--]:++tot;
}
void pushup(int o) {
tr[o].sum=tr[tr[o].ls].sum+tr[tr[o].rs].sum;
}
void update(int &o,int l,int r,int d,int w) {
if(!o) o=get_new();
if(l==r) {tr[o].sum+=w; return ;}
int mid=(l+r)/2;
if(d<=mid) update(tr[o].ls,l,mid,d,w);
else update(tr[o].rs,mid+1,r,d,w);
pushup(o);
}
void split(int &o,int &q,int l,int r,int s,int t) {
if(r<s||t<l) return ;
if(!o) return ;
if(s<=l&&r<=t) {q=o,o=0; return ;}
if(!q) q=get_new();
int mid=(l+r)/2;
if(s<=mid) split(tr[o].ls,tr[q].ls,l,mid,s,t);
if(mid<t) split(tr[o].rs,tr[q].rs,mid+1,r,s,t);
pushup(o); pushup(q);
}
int merge(int u,int v,int x,int y) {
if(!u||!v) return u+v;
if(x==y) {tr[u].sum+=tr[v].sum; return u;}
int mid=(x+y)/2;
tr[u].ls=merge(tr[u].ls,tr[v].ls,x,mid);
tr[u].rs=merge(tr[u].rs,tr[v].rs,mid+1,y);
pushup(u); del(v);
return u;
}
int query(int o,int l,int r,int s,int t) {
if(r<s||t<l) return 0;
if(s<=l&&r<=t) return tr[o].sum;
int mid=(l+r)/2;
return query(tr[o].ls,l,mid,s,t)+query(tr[o].rs,mid+1,r,s,t);
}
int kth(int o,int l,int r,int k) {
if(l==r) return l;
int mid=(l+r)/2;
if(tr[tr[o].ls].sum>=k) return kth(tr[o].ls,l,mid,k);
else return kth(tr[o].rs,mid+1,r,k-tr[tr[o].ls].sum);
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n,m,x,cntrt=1;
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>x,update(root[1],1,n,i,x);
while(m--){
int opt,p,x,y,t,q,k;
cin>>opt;
if(opt==0) cin>>p>>x>>y,split(root[1],root[++cntrt],1,n,x,y);
if(opt==1) cin>>p>>t,root[p]=merge(root[p],root[t],1,n);
if(opt==2) cin>>p>>x>>q,update(root[p],1,n,q,x);
if(opt==3) cin>>p>>x>>y,cout<<query(root[p],1,n,x,y)<<'\n';
if(opt==4) {
cin>>p>>k;
if(tr[root[p]].sum<k) cout<<"-1"<<'\n';
else cout<<kth(root[p],1,n,k)<<'\n';
}
}
}