20pts 求调
查看原帖
20pts 求调
1657369
__liujy楼主2025/7/2 13:18
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
typedef long long LL;
typedef unsigned int UI;
typedef unsigned long long ULL;
int n,m,a[N];
struct SegmentTree
{
	int l,r,mxa,mxb,cnt,se,add1,add2,add3,add4;
	LL sum;
	#define l(p) tr[p].l
	#define r(p) tr[p].r
	#define mxa(p) tr[p].mxa
	#define mxb(p) tr[p].mxb
	#define cnt(p) tr[p].cnt
	#define se(p) tr[p].se
	#define add1(p) tr[p].add1
	#define add2(p) tr[p].add2
	#define add3(p) tr[p].add3
	#define add4(p) tr[p].add4
	#define sum(p) tr[p].sum
}tr[N<<2];
inline int ls(int x){return x<<1;}
inline int rs(int x){return x<<1|1;}
inline void pushup(int p)
{
	sum(p)=sum(ls(p))+sum(rs(p));
	mxa(p)=max(mxa(ls(p)),mxa(rs(p)));
	mxb(p)=max(mxb(ls(p)),mxb(rs(p)));
	if(mxa(ls(p))==mxa(rs(p)))
	{
		se(p)=max(se(ls(p)),se(rs(p)));
		cnt(p)=cnt(ls(p))+cnt(rs(p));
	}
	else if(mxa(ls(p))>mxa(rs(p)))
	{
		se(p)=max(se(ls(p)),se(rs(p)));
		cnt(p)=cnt(ls(p));
	}
	else
	{
		se(p)=max(mxa(ls(p)),se(rs(p)));
		cnt(p)=cnt(p)=cnt(rs(p));
	}
}
inline void build(int p,int l,int r)
{
	l(p)=l,r(p)=r;
	if(l==r)
	{
		sum(p)=mxa(p)=mxb(p)=a[l];
		cnt(p)=1,se(p)=INT_MIN;
		return;
	}
	int mid=l+((r-l)>>1);
	build(ls(p),l,mid);
	build(rs(p),mid+1,r);
	pushup(p);
}
inline void update(int p,int k1,int k2,int k3,int k4)
{
	sum(p)+=1LL*k1*cnt(p)+1LL*k2*(r(p)-l(p)+1-cnt(p));
	mxb(p)=max(mxb(p),mxa(p)+k3);
	mxa(p)+=k1;
	if(se(p)!=INT_MIN) se(p)+=k2;
	add3(p)=max(add3(p),add1(p)+k3);
	add4(p)=max(add4(p),add2(p)+k4);
	add1(p)+=k1,add2(p)+=k2;
}
inline void spread(int p)
{
	int maxn=max(mxa(ls(p)),mxa(rs(p)));
	if(mxa(ls(p))==maxn) update(ls(p),add1(p),add2(p),add3(p),add4(p));
	else update(ls(p),add2(p),add2(p),add4(p),add4(p));
	if(mxa(rs(p))==maxn) update(rs(p),add1(p),add2(p),add3(p),add4(p));
	else update(rs(p),add2(p),add2(p),add4(p),add4(p));
	add1(p)=add2(p)=add3(p)=add4(p)=0;
}
inline void Add(int p,int l,int r,int k)
{
	if(l<=l(p)&&r(p)<=r)
	{
		sum(p)+=1LL*k*cnt(p)+1LL*k*(r(p)-l(p)+1-cnt(p));
		mxa(p)+=k;
		mxb(p)=max(mxb(p),mxa(p));
		if(se(p)!=INT_MIN) se(p)+=k;
		add1(p)+=k,add2(p)+=k;
		add3(p)=max(add3(p),add1(p));
		add4(p)=max(add4(p),add2(p));
		return;
	}
	spread(p);
	int mid=l(p)+((r(p)-l(p))>>1);
	if(l<=mid) Add(ls(p),l,r,k);
	if(mid<r) Add(rs(p),l,r,k);
	pushup(p);
}
inline void change(int p,int l,int r,int k)
{
	if(l>r(p)||r<l(p)||k>=mxa(p)) return;
	else if(l<=l(p)&&r(p)<=r&&se(p)<k)
	{
		int tmp=mxa(p)-k;
		sum(p)-=1LL*tmp*cnt(p);
		mxa(p)=k,add1(p)-=tmp;
		return;
	}
	spread(p);
	change(ls(p),l,r,k);
	change(rs(p),l,r,k);
	pushup(p);
}
inline LL query(int p,int l,int r)
{
	if(l<=l(p)&&r(p)<=r) return sum(p);
	spread(p);
	int mid=l(p)+((r(p)-l(p))>>1);
	LL ans=0;
	if(l<=mid) ans+=query(ls(p),l,r);
	if(mid<r) ans+=query(rs(p),l,r);
	return ans;
}
inline int getmaxa(int p,int l,int r)
{
	if(l<=l(p)&&r(p)<=r) return mxa(p);
	spread(p);
	int mid=l(p)+((r(p)-l(p))>>1),mx=INT_MIN;
	if(l<=mid) mx=max(mx,getmaxa(ls(p),l,r));
	if(mid<r) mx=max(mx,getmaxa(rs(p),l,r));
	return mx;
}
inline int getmaxb(int p,int l,int r)
{
	if(l<=l(p)&&r(p)<=r) return mxb(p);
	spread(p);
	int mid=l(p)+((r(p)-l(p))>>1),mx=INT_MIN;
	if(l<=mid) mx=max(mx,getmaxb(ls(p),l,r));
	if(mid<r) mx=max(mx,getmaxb(rs(p),l,r));
	return mx;
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i];
	build(1,1,n);
	while(m--)
	{
		int type,l,r;
		cin>>type>>l>>r;
		if(type==1)
		{
			int k;cin>>k;
			Add(1,l,r,k);
		}
		else if(type==2)
		{
			int k;cin>>k;
			change(1,l,r,k);
		}
		else if(type==3) cout<<query(1,l,r)<<'\n';
		else if(type==4) cout<<getmaxa(1,l,r)<<'\n';
		else cout<<getmaxb(1,l,r)<<'\n';
	}
	return 0;
}
2025/7/2 13:18
加载中...