【模板】非旋转Treap

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hzj1054689699/article/details/84636215

Code

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#define fo(i,a,b) for(int i=a;i<=b;++i)
#define fod(i,a,b) for(int i=a;i>=b;--i)
#define N 100005
#define LL long long
using namespace std;
int n1,t[N][2],key[N],q,n,rt,st[N];
LL vl[N],sm[N],lz[N],sz[N];
void upd(int k,LL v)
{
	if(k) lz[k]+=v,sm[k]+=v*sz[k],vl[k]+=v;
}
void down(int k)
{
	upd(t[k][0],lz[k]),upd(t[k][1],lz[k]);
	lz[k]=0;
}
void up(int k)
{
	sz[k]=sz[t[k][0]]+sz[t[k][1]]+1;
	sm[k]=sm[t[k][0]]+sm[t[k][1]]+vl[k];
}
void split(int &k,int &x,int v)
{
	if(!k) {x=0;return;}
	down(k);
	if(sz[t[k][0]]>=v) split(t[k][0],x,v),swap(t[k][0],x),up(k),swap(k,x);
	else split(t[k][1],x,v-sz[t[k][0]]-1),up(k);
}
int merge(int x,int y)
{
	if(!x) return y;
	if(!y) return x;
	down(x),down(y);
	if(key[x]<=key[y]) {t[x][1]=merge(t[x][1],y);up(x);return x;}
	else {t[y][0]=merge(x,t[y][0]);up(y);return y;}
}
int build()
{
	int top=1;
	key[0]=-2147483647;
	fo(i,1,n)
	{
		while(top&&key[st[top]]>key[i]) up(st[top]),st[top--]=0;
		t[i][0]=t[st[top]][1],t[st[top]][1]=i;
		st[++top]=i; 
	}
	fod(i,top,2) up(st[i]);
	key[0]=sz[0]=sm[0]=vl[0]=t[0][1]=t[0][0]=0;
	return st[2];
}
int main()
{
	cin>>n>>q;
	srand(13271815);
	fo(i,1,n) scanf("%lld",&vl[i]),key[i]=rand()*rand()-rand();
	rt=build();
	fo(i,1,q)
	{
		int p,x,y,u=rt,v,w;
		LL z;
		scanf("%d%d%d",&p,&x,&y);
		if(p==1) 
		{
			scanf("%lld",&z);
			split(u,v,x-1);
			split(v,w,y-x+1);
			upd(v,z);
			u=merge(u,v),rt=merge(u,w);
		}
		else
		{
			split(u,v,x-1);
			split(v,w,y-x+1);
			printf("%lld\n",sm[v]);
			u=merge(u,v),rt=merge(u,w);
		}
	}
}

猜你喜欢

转载自blog.csdn.net/hzj1054689699/article/details/84636215
今日推荐