线段树分裂求调
查看原帖
线段树分裂求调
1425894
L_J_Der楼主2025/1/22 15:55

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';
		}
	}
}
2025/1/22 15:55
加载中...