线段树板子20pts求助
查看原帖
线段树板子20pts求助
102709
zjy1412楼主2022/9/29 20:41

只A了5,6两个点说明是操作2有问题,但是de不出来。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define ll long long
#define lp (p<<1)
#define rp (p<<1|1)
#define debug printf("zjy\n")
inline ll read(){
	ll a=0,b=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')b=-1;c=getchar();}
	while(isdigit(c)){a=a*10+c-'0';c=getchar();}
	return a*b;
}
const ll N=5e5+50;
struct st{
	ll maxa,maxb,se,cnt,sum,l,r,add1,add2,add3,add4;
	#define l(x) t[x].l
	#define r(x) t[x].r
	#define add1(x) t[x].add1
	#define add2(x) t[x].add2
	#define add3(x) t[x].add3
	#define add4(x) t[x].add4
	#define maxa(x) t[x].maxa
	#define maxb(x) t[x].maxb
	#define se(x) t[x].se
	#define cnt(x) t[x].cnt
	#define sum(x) t[x].sum
}t[N<<2];
ll n,m,a[N];
void pushup(ll p){
	maxa(p)=max(maxa(lp),maxa(rp));
	maxb(p)=max(maxb(lp),maxb(rp));
	sum(p)=sum(lp)+sum(rp);
	if(maxa(lp)==maxa(rp)){
		cnt(p)=cnt(lp)+cnt(rp);
		se(p)=max(se(lp),se(rp));
	}
	if(maxa(lp)>maxa(rp)){
		cnt(p)=cnt(lp);
		se(p)=max(se(lp),maxa(rp));
	}
	if(maxa(lp)<maxa(rp)){
		cnt(p)=cnt(rp);
		se(p)=max(se(rp),maxa(lp));
	}
}
void build(ll p,ll l,ll r){
	l(p)=l;r(p)=r;
	if(l==r){
		maxa(p)=maxb(p)=sum(p)=a[l];
		cnt(p)=1;
		se(p)=-2e9;
		return;
	}
	ll mid=l+r>>1;
	build(lp,l,mid);build(rp,mid+1,r);
	pushup(p);
}
void change(ll p,ll k1,ll k2,ll k3,ll k4){
	sum(p)+=k1*cnt(p)+k2*(r(p)-l(p)+1-cnt(p));
	maxb(p)=max(maxb(p),maxa(p)+k3);
	maxa(p)+=k1;
	if(se(p)!=-2e9)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;
}
void pushdown(ll p){
	ll maxn=(maxa(lp),maxa(rp));
	if(maxa(lp)==maxn)change(lp,add1(p),add2(p),add3(p),add4(p));
	else change(lp,add2(p),add2(p),add4(p),add4(p));
	if(maxa(rp)==maxn)change(rp,add1(p),add2(p),add3(p),add4(p));
	else change(rp,add2(p),add2(p),add4(p),add4(p));
	add1(p)=add2(p)=add3(p)=add4(p)=0;
}
void add(ll p,ll l,ll r,ll k){
	if(l(p)>=l&&r(p)<=r){
		maxa(p)+=k;
		sum(p)+=k*(r(p)-l(p)+1);
		maxb(p)=max(maxb(p),maxa(p));
		if(se(p)!=-2e9)se(p)+=k;
		add1(p)+=k;add2(p)+=k;
		add3(p)=max(add3(p),add1(p));
		add4(p)=max(add4(p),add2(p));
		return;
	}
	pushdown(p);
	ll mid=l(p)+r(p)>>1;
	if(l<=mid)add(lp,l,r,k);
	if(r>mid)add(rp,l,r,k);
	pushup(p);
}
void work_min(ll p,ll l,ll r,ll k){
	if(maxa(p)<=k)return;
	if(l(p)>=l&&r(p)<=r&&k>se(p)){
		ll zjy=maxa(p)-k;
		sum(p)-=cnt(p)*zjy;
		add1(p)-=zjy;
		maxa(p)=k;
		return;
	}
	pushdown(p);
	ll mid=l(p)+r(p)>>1;
	if(l<=mid)work_min(lp,l,r,k);
	if(r>mid)work_min(rp,l,r,k);
	pushup(p);
}
ll query_sum(ll p,ll l,ll r){
	if(l(p)>=l&&r(p)<=r)return sum(p);
	pushdown(p);
	ll mid=l(p)+r(p)>>1,res=0;
	if(l<=mid)res+=query_sum(lp,l,r);
	if(r>mid)res+=query_sum(rp,l,r);
	return res;
}
 
ll query_a(ll p,ll l,ll r){
	if(l(p)>=l&&r(p)<=r)return maxa(p);
	pushdown(p);
	ll mid=l(p)+r(p)>>1,res=-2e9;
	if(l<=mid)res=query_a(lp,l,r);
	if(r>mid)res=max(res,query_a(rp,l,r));
	return res;
}
ll query_b(ll p,ll l,ll r){
	if(l(p)>=l&&r(p)<=r)return maxb(p);
	pushdown(p);
	ll mid=l(p)+r(p)>>1,res=-2e9;
	if(l<=mid)res=query_b(lp,l,r);
	if(r>mid)res=max(res,query_b(rp,l,r));
	return res;
}
int main(){
	n=read();m=read();
	for(ll i=1;i<=n;i++)a[i]=read();
	build(1,1,n);
	for(ll i=1,op,l,r,k;i<=m;i++){
		op=read();l=read();r=read();
		if(op==1){
			k=read();
			add(1,l,r,k);
		}
		if(op==2){
			k=read();
			work_min(1,l,r,k);
		}
		if(op==3){
			printf("%lld\n",query_sum(1,l,r));
		}
		if(op==4){
			printf("%lld\n",query_a(1,l,r));
		}
		if(op==5){
			printf("%lld\n",query_b(1,l,r));
		}
	}
	return 0;
}
2022/9/29 20:41
加载中...