求助,线段树30分,A第1、5、6点
查看原帖
求助,线段树30分,A第1、5、6点
374756
忘怜城羡楼主2022/8/30 21:50

RT,mine是当前最大值,maxe是历史最大值,ls是左孩子,rs是右孩子,second是严格次大值

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN=5e5+10;
struct node{
	int ls,rs,maxe,mine,l,r,second,cnt,lazy1,lazy2,lazy3,lazy4;
	long long sum;
}tree[4*MAXN];
int a[4*MAXN];
int tot=1;
inline void lazy(int a1,int a2,int a3,int a4,int p)
{
	tree[p].sum+=1LL*a1*tree[p].cnt+1LL*a2*(tree[p].r-tree[p].l+1-tree[p].cnt);
	tree[p].maxe=max(tree[p].maxe,tree[p].mine+a3);
	tree[p].mine+=a1;
	if(tree[p].second!=-1e18)
	tree[p].second+=a2;
	tree[p].lazy3=max(tree[p].lazy3,tree[p].lazy1+a3);
	tree[p].lazy4=max(tree[p].lazy4,tree[p].lazy2+a4);
	tree[p].lazy1+=a1;
	tree[p].lazy2+=a2;
}
inline void pushdown(int p)
{
	int l=tree[p].ls,r=tree[p].rs;
	int maxx=max(tree[l].mine,tree[r].mine);
	if(tree[l].mine==maxx)
	lazy(tree[p].lazy1,tree[p].lazy2,tree[p].lazy3,tree[p].lazy4,tree[p].ls);
	else
	lazy(tree[p].lazy2,tree[p].lazy2,tree[p].lazy4,tree[p].lazy4,tree[p].ls);
	if(tree[r].mine==maxx)
	lazy(tree[p].lazy1,tree[p].lazy2,tree[p].lazy3,tree[p].lazy4,tree[p].rs);
	else
	lazy(tree[p].lazy2,tree[p].lazy2,tree[p].lazy4,tree[p].lazy4,tree[p].rs);
	tree[p].lazy1=tree[p].lazy2=tree[p].lazy3=tree[p].lazy4=0;
}
inline void pushup(int p)
{
	int l=tree[p].ls,r=tree[p].rs;
	tree[p].sum=tree[l].sum+tree[r].sum;
	tree[p].mine=max(tree[l].mine,tree[r].mine);
	tree[p].maxe=max(tree[l].maxe,tree[r].maxe);
	if(tree[l].mine==tree[r].mine)
	{
		tree[p].second=max(tree[l].second,tree[r].second);
		tree[p].cnt=tree[l].cnt+tree[r].cnt;
	}
	if(tree[l].mine>tree[r].mine)
	{
		tree[p].second=max(tree[l].second,tree[r].mine);
		tree[p].cnt=tree[l].cnt;
	}
	if(tree[l].mine<tree[r].mine)
	{
		tree[p].second=max(tree[l].mine,tree[r].second);
		tree[p].cnt=tree[r].cnt;
	}
}
inline void modify(int p,int l,int r,int k)
{
	if(l<=tree[p].l&&tree[p].r<=r)
	{
		tree[p].sum+=(tree[p].r-tree[p].l+1)*k;
		tree[p].maxe=max(tree[p].maxe,tree[p].mine+k);
		tree[p].mine+=k;
		if(tree[p].second!=-1e18)
		tree[p].second+=k;
		tree[p].lazy1+=k;
		tree[p].lazy2+=k;
		tree[p].lazy3=max(tree[p].lazy3,tree[p].lazy1);
		tree[p].lazy4=max(tree[p].lazy4,tree[p].lazy2);
		return ;
	}
	if(tree[p].l==-1)
	return ;
	pushdown(p);
	int mid=(tree[p].l+tree[p].r)>>1;
	if(l<=mid)
	modify(tree[p].ls,l,r,k);
	if(mid<r)
	modify(tree[p].rs,l,r,k);	
	pushup(p);
	return ;
}
inline long long sigma(int p,int l,int r)
{
	if(l<=tree[p].l&&tree[p].r<=r)
	return tree[p].sum;
	pushdown(p);
	int mid=(tree[p].l+tree[p].r)>>1;
	long long ans=0;
	if(l<=mid)
	ans+=sigma(tree[p].ls,l,r);
	if(mid<r)
	ans+=sigma(tree[p].rs,l,r);
	return ans;
}
inline int minn(int p,int l,int r)
{
	if(l<=tree[p].l&&tree[p].r<=r)
	return tree[p].mine;
	pushdown(p);
	int mid=(tree[p].l+tree[p].r)>>1,ans=-1e18;
	if(l<=mid)
	ans=max(ans,minn(tree[p].ls,l,r));
	if(mid<r)
	ans=max(ans,minn(tree[p].rs,l,r));
	return ans;
}
inline int maxn(int p,int l,int r)
{
	if(l<=tree[p].l&&tree[p].r<=r)
	return tree[p].maxe;
	pushdown(p);
	int mid=(tree[p].l+tree[p].r)>>1,ans=-1e18;
	if(l<=mid)
	ans=max(ans,maxn(tree[p].ls,l,r));
	if(mid<r)
	ans=max(ans,maxn(tree[p].rs,l,r));
	return ans;
}
inline void change(int p,int l,int r,int k)
{
	if(l<=tree[p].l&&tree[p].r<=r&&tree[p].second<k)
	{
		int v=tree[p].mine-k;
		tree[p].sum-=v*tree[p].cnt;
		tree[p].mine=k;
		tree[p].lazy1-=v;
		return ;
	}
	if(tree[p].ls==-1)
	return ;
	pushdown(p);
	int mid=(tree[p].l+tree[p].r)>>1;
	if(l<=mid)
	change(tree[p].ls,l,r,k);
	if(mid<r)
	change(tree[p].rs,l,r,k);
	pushup(p);
}
inline void build(int p,int l,int r)
{
	tree[p].l=l;
	tree[p].r=r;
	if(l==r)
	{
		tree[p].sum=tree[p].maxe=tree[p].mine=a[l];
		tree[p].ls=tree[p].rs=-1;
		tree[p].second=-1e18;
		tree[p].cnt=1;
		return ;
	}
	tot++;
	int mid=l+r>>1;
	tree[p].ls=tot;
	build(tot,l,mid);
	tot++;
	tree[p].rs=tot;
	build(tot,mid+1,r);
	pushup(p);
}
signed main()
{
	int n,m;
	scanf("%lld%lld",&n,&m);
	for(int i(1);i<=n;++i)
	scanf("%lld",&a[i]);
	build(1,1,n);
	while(m--)
	{
		int op,l,r,k;
		scanf("%lld",&op);
		if(op==1)
		{
			scanf("%lld%lld%lld",&l,&r,&k);
			modify(1,l,r,k);
		}
		if(op==2)
		{
			scanf("%lld%lld%lld",&l,&r,&k);
			change(1,l,r,k);
		}
		if(op==3)
		{
			scanf("%lld%lld",&l,&r);
			printf("%lld\n",sigma(1,l,r));
		}
		if(op==4)
		{
			scanf("%lld%lld",&l,&r);
			printf("%lld\n",minn(1,l,r));
		}
		if(op==5)
		{
			scanf("%lld%lld",&l,&r);
			printf("%lld\n",maxn(1,l,r));
		}
	}
	return 0;
}
2022/8/30 21:50
加载中...