#include<bits/stdc++.h> using namespace std;
typedef long long ll; #define re register const int maxn=2e5+5; #define INF 0x3f3f3f3f
#define ls(x) st[x].l #define rs(x) st[x].r
int n,m,tot,op,p,c=1; int root[maxn];
ll a[maxn];
struct SegmentTree{ ll v; int l,r; }st[maxn<<6];
inline void push_up(int rt){ st[rt].v=st[ls(rt)].v+st[rs(rt)].v; }
int build(int l,int r){ int rt=++tot; if(l==r){ st[rt].v=a[l]; return rt; } int mid=(l+r)>>1; ls(rt)=build(l,mid); rs(rt)=build(mid+1,r); push_up(rt); return rt; }
int split(int rt,int l,int r,int ql,int qr){ int o=++tot; if(ql==l&&qr==r){ st[o]=st[rt]; st[rt].v=ls(rt)=rs(rt)=0; return o; } int mid=(l+r)>>1; if(qr<=mid){ ls(o)=split(ls(rt),l,mid,ql,qr); }else if(ql>mid){ rs(o)=split(rs(rt),mid+1,r,ql,qr); }else{ ls(o)=split(ls(rt),l,mid,ql,mid); rs(o)=split(rs(rt),mid+1,r,mid+1,qr); } push_up(rt);push_up(o); return o; }
int merge(int p,int q){ if(!p||!q)return p|q; int rt=++tot; st[rt].v=st[p].v+st[q].v; ls(rt)=merge(ls(p),ls(q)); rs(rt)=merge(rs(p),rs(q)); return rt; }
void modify(int rt,int l,int r,int pos,int val){ if(l==r){ st[rt].v+=val; return; } int mid=(l+r)>>1; if(pos<=mid){ if(ls(rt)==0)ls(rt)=++tot; modify(ls(rt),l,mid,pos,val); } else { if(rs(rt)==0)rs(rt)=++tot; modify(rs(rt),mid+1,r,pos,val); } push_up(rt); }
ll query(int rt,int l,int r,int ql,int qr){ if(ql>r||qr<l)return 0; if(ql<=l&&qr>=r){ return st[rt].v; } int mid=(l+r)>>1; return query(ls(rt),l,mid,ql,qr)+query(rs(rt),mid+1,r,ql,qr); }
int kth(int rt,int l,int r,int k){ if(l==r)return l; int mid=(l+r)>>1; if(st[ls(rt)].v>=k)return kth(ls(rt),l,mid,k); else return kth(rs(rt),mid+1,r,k-st[ls(rt)].v); }
inline ll read(){ ll x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();} return x*f; }
int main(){ #ifdef LawrenceSivan freopen("aa.in","r",stdin); freopen("aa.out","w",stdout); #endif n=read();m=read(); for(re int i=1;i<=n;i++){ a[i]=read(); } root[1]=build(1,n); for(re int i=1;i<=m;i++){ op=read();p=read(); if(op==0){ int x=read(),y=read(); root[++c]=split(root[p],1,n,x,y); } if(op==1){ int x=read(); root[p]=merge(root[p],root[x]); } if(op==2){ int x=read(),y=read(); modify(root[p],1,n,y,x); } if(op==3){ int x=read(),y=read(); printf("%lld\n",query(root[p],1,n,x,y)); } if(op==4){ ll k=read(); if(query(root[p],1,n,1,n)<k)printf("-1\n"); else printf("%d\n",kth(root[p],1,n,k)); } }
return 0; }
|