进士后人
  • 板块P1001 A+B Problem
  • 楼主lfxxx_
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/11/20 14:33
  • 上次更新2024/11/20 14:34:11
查看原帖
进士后人
795344
lfxxx_楼主2024/11/20 14:33

写文艺平衡树的时候上传max标记要判断是否有左右儿子!

不然会挂(like this)

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
mt19937 rng(time(0));
int root,tot;
struct node{
	int val,pri,ls,rs,sz;
	int sum,maxn;
	int rev,add;
}tr[N];
int New(int x)
{
	++tot;
	tr[tot].sum=tr[tot].maxn=tr[tot].val=x;
	tr[tot].pri=rng();
	tr[tot].rev=tr[tot].add=tr[tot].ls=tr[tot].rs=0;
	tr[tot].sz=1;
	return tot;
}
void pushup(int p)
{
	tr[p].sum=tr[tr[p].ls].sum+tr[tr[p].rs].sum+tr[p].val;
	tr[p].maxn=tr[p].val;
	tr[p].maxn=max(tr[p].maxn,tr[tr[p].ls].maxn);
	tr[p].maxn=max(tr[p].maxn,tr[tr[p].rs].maxn);
	tr[p].sz=tr[tr[p].ls].sz+tr[tr[p].rs].sz+1;
}
void addtag(int p,int d)
{
	tr[p].val+=d;
	tr[p].add+=d;
	tr[p].sum+=tr[p].sz*d;
	tr[p].maxn+=d;
}
void pushdown(int p)
{
	if(tr[p].rev)
	{
		swap(tr[p].ls,tr[p].rs);
		if(tr[p].ls)tr[tr[p].ls].rev^=1;
		if(tr[p].rs)tr[tr[p].rs].rev^=1;
		tr[p].rev=0;
	}
	if(tr[p].add)
	{
		if(tr[p].ls)addtag(tr[p].ls,tr[p].add);
		if(tr[p].rs)addtag(tr[p].rs,tr[p].add);
		tr[p].add=0;
	}	
}
void split(int p,int k,int &L,int &R)
{
	if(!p)
	{
		L=R=0;
		return ;
	}
	pushdown(p);
	if(tr[tr[p].ls].sz<k)
	{
		L=p;
		split(tr[p].rs,k-tr[tr[p].ls].sz-1,tr[p].rs,R);
	}
	else
	{
		R=p;
		split(tr[p].ls,k,L,tr[p].ls);
	}
	pushup(p);
}
int merge(int L,int R)
{
	if(!L||!R)
		return L|R;
	if(tr[L].pri<=tr[R].pri)
	{
		pushdown(L);
		tr[L].rs=merge(tr[L].rs,R);
		pushup(L);
		return L;
	}
	pushdown(R);
	tr[R].ls=merge(L,tr[R].ls);
	pushup(R);
	return R;
}
void REVERSE(int l,int r)
{
	int L,R,p; 
	split(root,l-1,L,R);
	split(R,r-l+1,R,p);
	tr[R].rev^=1;
	root=merge(L,merge(R,p)); 
}
void ADD(int l,int r,int d)
{
	int L,R,p;
	split(root,l-1,L,R);
	split(R,r-l+1,R,p);
	addtag(R,d);
	root=merge(L,merge(R,p));
}
int GETSUM(int l,int r)
{
	int L,R,p;
	split(root,l-1,L,R);
	split(R,r-l+1,R,p);
	int res=tr[R].sum;
	root=merge(L,merge(R,p));
	return res;
} 
int GETMAX(int l,int r)
{
	int L,R,p;
	split(root,l-1,L,R);
	split(R,r-l+1,R,p);
	int res=tr[R].maxn;
	root=merge(L,merge(R,p));
	return res;
}
signed main()
{
	int x,y;
	cin>>x>>y;
	for(int i=1;i<=4;++i)
		root=merge(root,New(0));
	ADD(1,2,x);
	ADD(3,4,y);
	REVERSE(1,2);
	REVERSE(3,4);
	cout<<GETSUM(1,2)-GETMAX(1,2)+GETSUM(3,4)-GETMAX(3,4);
}
2024/11/20 14:33
加载中...