萌新求助 fhq_treap 求线段树1
查看原帖
萌新求助 fhq_treap 求线段树1
342076
Union_of_Britain楼主2021/8/18 22:24

就是把文艺平衡树的反转变成加法标记?

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e5+5;
int val[maxn],sze[maxn],l[maxn],r[maxn],pri[maxn],cnt=0,rt=0;
bool tag[maxn];
int a[maxn];
int x,y,z;
void pushup(int k){
	sze[k]=sze[l[k]]+sze[r[k]]+1;val[k]=val[l[k]]+val[r[k]]+a[k];
}
int newnode(int v){
	val[++cnt]=v,sze[cnt]=1,l[cnt]=r[cnt]=0,pri[cnt]=rand(); 
    return cnt;
}
void add(int k,int v){
	tag[k]+=v;
	val[k]+=sze[k]*v;
}
void pushdown(int k){
	add(l[k],tag[k]);
	add(r[k],tag[k]);
	tag[k]=0;
}
void split(int now,int k,int &x,int &y){
	if(!now){
        x=y=0;return ;
    }
	pushdown(now);
	if(sze[l[now]]+1<=k)x=now,split(r[now],k-(sze[l[now]]+1),r[now],y);
	else y=now,split(l[now],k,x,l[now]);
	pushup(now);
}
int merge(int x,int y){
    if(!x||!y)return x+y;
	if(pri[x]<pri[y]){
		pushdown(x);
		r[x]=merge(r[x],y);
		pushup(x);
		return x;
	}else{
		pushdown(y);
		l[y]=merge(x,l[y]);pushup(y);
		return y;
	}
}

void print(int now){
	if(!now)return ;
    pushdown(now);
	print(l[now]);cout<<val[now]<<" ";
	print(r[now]);
}
int n,m;
signed main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>a[i],rt=merge(rt,newnode(a[i]));
	for(int i=1;i<=m;i++){
		int l,r,k;
		int ch;
		cin>>ch>>l>>r;
		split(rt,l-1,x,y);
		split(y,r-l+1,y,z);
		if(ch==2){
			cout<<val[y]<<endl;
		}
		else{
			cin>>k;
			add(y,k);
		}
		rt=merge(merge(x,y),z);
	}
	return 0;
}
2021/8/18 22:24
加载中...