求助fhqtreap就对了一个点。。
查看原帖
求助fhqtreap就对了一个点。。
412902
laplace_oo楼主2022/10/29 08:05
/// @brief FHQ Treap
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
int n,m,a[N];
int root,cnt;
int lc[N],rc[N],siz[N];
int val[N],sum[N],key[N],tag[N];
void add(int p,int k)
{
	sum[p]+=siz[p]*k;
	tag[p]+=k;
	val[p]+=k;
}
void up(int p)
{
	siz[p]=siz[lc[p]]+siz[rc[p]]+1;
	sum[p]=sum[lc[p]]+sum[rc[p]]+val[p];
}
int neo(int v)
{
	cnt++;
	val[cnt]=v;
	key[cnt]=rand();
	siz[cnt]=1;
	return cnt;
}
void dwd(int p)
{
	if(lc[p])
	{
		sum[lc[p]]+=siz[lc[p]]*tag[p];
		val[lc[p]]+=tag[p];
		tag[lc[p]]+=tag[p];
	}
	if(rc[p])
	{
		sum[rc[p]]+=siz[rc[p]]*tag[p];
		val[rc[p]]+=tag[p];
		tag[rc[p]]+=tag[p];
	}
	tag[p]=0;
}
void split(int p,int &x,int &y,int k)
{
	if(!p)
	{
		x=y=0;
		return;
	}
	dwd(p);
	if(siz[lc[p]]+1<=k)
	{
		x=p;
		split(rc[p],rc[x],y,k-siz[lc[p]]-1);
	}
	else
	{
		y=p;
		split(lc[p],x,lc[y],k);
	}
	up(p);
}
int merge(int x,int y)
{
	if(!x||!y)return x|y;
	dwd(x);
	dwd(y);
	if(key[x]<=key[y])
	{
		rc[x]=merge(rc[x],y);
		up(x);
		return x;
	}
	else
	{
		lc[y]=merge(x,lc[y]);
		up(y);
		return y;
	}
}
int build(int l,int r)
{
	if(l==r)return neo(a[l]);
	int mid=(l+r)>>1;
	return merge(build(l,mid),build(mid+1,r));
}
void addrange(int l,int r,int k)
{
	int x,y,z;
	split(root,x,y,r);
	split(x,x,z,l-1);
	add(z,k);
	root=merge(x,merge(z,y));
}
int askrange(int l,int r)
{
	int x,y,z;
	split(root,x,y,r);
	split(x,x,z,l-1);
	int res=sum[z];
	root=merge(x,merge(z,y));
	return res;
}
signed main()
{
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;++i)
	{
		scanf("%lld",&a[i]);
	}
	root=build(1,n);
	for(int i=1;i<=m;++i)
	{
		int o,x,y;
		scanf("%lld%lld%lld",&o,&x,&y);
		if(o==1)
		{
			int k;
			scanf("%lld",&k);
			addrange(x,y,k);
		}
		else
		{
			printf("%lld\n",askrange(x,y));
		}
	}
	return 0;
}

2022/10/29 08:05
加载中...