20pts求助
查看原帖
20pts求助
797897
_QyGyQ_楼主2024/5/5 17:05
#include<bits/stdc++.h>
#define int long long
#define lc(p) (p<<1)
#define rc(p) (p<<1|1)
#define debug puts("-----------")
#define endl puts("")
#define re register
#define in inline
using namespace std;
const int N=2e5+7;

char *p1,*p2,buf[N];
#define nc() (p1==p2 && (p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
in int read(){
    int x=0,f=1;
    char ch=nc();
    while(ch<48||ch>57){
        if(ch=='-') f=-1;
        ch=nc();
    }
    while(ch>=48&&ch<=57) x=x*10+ch-48,ch=nc();
   	return x*f;
}

struct node{
	int l,r,sum;
};
node tree[N<<4];
int root[N];
int n,m,Root;
int dele[N],Del;
int tot;
in int newNode(){
	if(Del) return dele[Del--];
	else return ++tot;
}
in void push_up(int p){
	tree[p].sum=tree[tree[p].l].sum+tree[tree[p].r].sum;
}
in void update(int &p,int pl,int pr,int i,int v){
	if(!p) p=newNode();
	if(pl==pr){
		tree[p].sum+=v;
		return ;
	}
	int mid=pl+pr>>1;
	if(i<=mid) update(tree[p].l,pl,mid,i,v);
	else update(tree[p].r,mid+1,pr,i,v);
	push_up(p);
}
in void Delete(int p){
	tree[p].sum=0;
	tree[p].l=tree[p].r=0;
	dele[++Del]=p;
}
in void merge(int &a,int b,int pl,int pr){
	if(!a||!b){
		a+=b;
		return ;
	}
	if(pl==pr){
		tree[a].sum+=tree[b].sum;
		Delete(b);
		return ;
	}
	int mid=pl+pr>>1;
	merge(tree[a].l,tree[b].l,pl,mid);
	merge(tree[a].r,tree[b].r,mid+1,pr);
	push_up(a);
	Delete(b);
}
in void split(int a,int &b,int p){
	if(!a) return ;
	b=newNode();
	int v=tree[tree[a].l].sum;
	if(v<p) split(tree[a].r,tree[b].r,p-v);
	else{
		swap(tree[a].r,tree[b].r);
	}
	if(v>p){
		split(tree[a].l,tree[b].l,p);
		tree[b].sum=tree[a].sum-p;
		tree[a].sum=p;
	}
}
in int querySum(int p,int pl,int pr,int L,int R){
	if(pl==L&&pr==R){
		return tree[p].sum;
	}
	int mid=pl+pr>>1;
	if(R<=mid) return querySum(tree[p].l,pl,mid,L,R);
	else if(L>mid) return querySum(tree[p].r,mid+1,pr,L,R);
	else{
		return querySum(tree[p].l,pl,mid,L,mid)+querySum(tree[p].r,mid+1,pr,mid+1,R);
	}
}
in int queryVal(int p,int pl,int pr,int rank){
	if(pl==pr) return pl;
	int mid=pl+pr>>1;
	if(tree[tree[p].l].sum<rank) return queryVal(tree[p].r,mid+1,pr,rank-tree[tree[p].l].sum);
	else{
		return queryVal(tree[p].l,pl,mid,rank);
	}
}
signed main(){
	n=read(),m=read();
	Root=1;
	for(re int i=1;i<=n;i++){
		int v=read();
		update(root[1],1,n,i,v);
	}
	for(re int i=1;i<=m;i++){
		int op=read();
		if(op==0){
			int now=0;
			int p=read(),x=read(),y=read();
			int sum1=querySum(root[p],1,n,1,y);
			int sum2=querySum(root[p],1,n,x,y);
			split(root[p],root[++Root],sum1-sum2);
			split(root[Root],now,sum2);
			merge(root[p],now,1,n);
		}
		else if(op==1){
			int p=read(),t=read();
			merge(root[p],root[t],1,n);
		}
		else if(op==2){
			int p=read(),x=read(),q=read();
			update(root[p],1,n,q,x);
		}
		else if(op==3){
			int p=read(),x=read(),y=read();
			printf("%lld\n",querySum(root[p],1,n,x,y));
		}
		else{
			int p=read(),rank=read();
			if(rank<0||tree[root[p]].sum<rank) puts("-1");
			else printf("%lld\n",queryVal(root[p],1,n,rank));
		}
	}
	return 0;
}
2024/5/5 17:05
加载中...