调线段树真是一件减少阳寿的事
查看原帖
调线段树真是一件减少阳寿的事
502707
2021hych楼主2022/1/31 16:30

本人调线段树调的快疯了,30分求助,样例都是错的。

#include<bits/stdc++.h>
#define MAXN 500001
#define int long long
using namespace std;
const int inf=0x7fffffff;
int n,m,a[MAXN],opt,l,r,k,v;
struct Potential_SegmentTree {
	int l,r,cnt,sum,add1,add2,add3,add4,fm1,fm2,sm;
	#define l(x) tree[x].l
	#define r(x) tree[x].r
	#define cnt(x) tree[x].cnt
	#define sum(x) tree[x].sum
	#define add1(x) tree[x].add1
	#define add2(x) tree[x].add2
	#define add3(x) tree[x].add3
	#define add4(x) tree[x].add4
	#define fm1(x) tree[x].fm1
	#define fm2(x) tree[x].fm2
	#define sm(x) tree[x].sm
	#define ls(x) x<<1
	#define rs(x) x<<1|1
}tree[MAXN<<2];
void merge(int p) {
	sum(p)=sum(ls(p))+sum(rs(p));
	fm1(p)=max(fm1(ls(p)),fm1(rs(p)));
	fm2(p)=max(fm2(ls(p)),fm2(rs(p)));	
	if(fm1(ls(p))<fm1(rs(p))) {
		sm(p)=max(fm1(ls(p)),sm(rs(p)));
		cnt(p)=cnt(rs(p));
	}
	if(fm1(ls(p))==fm1(rs(p))) {
		sm(p)=max(sm(ls(p)),sm(rs(p)));
		cnt(p)=cnt(ls(p))+cnt(rs(p));
	}
	if(fm1(ls(p))>fm1(rs(p))) {
		sm(p)=max(sm(ls(p)),fm1(rs(p)));
		cnt(p)=cnt(ls(p));
	}
}
void spread_(int p,int num1,int num2,int num3,int num4) {
	sum(p)+=num1*cnt(p)+num3*(r(p)-l(p)+1-cnt(p));
	fm1(p)+=num1;
	fm2(p)=max(fm2(p),fm1(p)+num2);
	add1(p)+=num1;
	add2(p)+=num3;
	add3(p)=max(add3(p),add1(p)+num2);
	add4(p)=max(add4(p),add2(p)+num4);
	if(sm(p)!=-inf) sm(p)+=num3;
}
void spread(int p) {
	int maxn=max(fm1(ls(p)),fm1(rs(p)));
	if(fm1(ls(p))==maxn) spread_(ls(p),add1(p),add3(p),add2(p),add4(p));
	else spread_(ls(p),add2(p),add4(p),add2(p),add4(p));
	if(fm1(rs(p))==maxn) spread_(rs(p),add1(p),add3(p),add2(p),add4(p));
	else spread_(rs(p),add2(p),add4(p),add2(p),add4(p));
	add1(p)=0;
	add2(p)=0;
	add3(p)=0;
	add4(p)=0;
} 
void build(int p,int l,int r) {
	l(p)=l,r(p)=r;
	if(l==r) {
		sum(p)=a[l];
		fm1(p)=a[l];
		fm2(p)=a[l];
		sm(p)=-inf;
		cnt(p)=1;
		return;
	} 
	int mid=l+r>>1;
	build(ls(p),l,mid);
	build(rs(p),mid+1,r);
	merge(p);
}
void change1(int p,int l,int r,int d) {
	if(l(p)>r||r(p)<l) return;
	if(l<=l(p)&&r(p)<=r) {
		spread_(p,d,d,d,d);
		return;
	}
	spread(p);
	change1(ls(p),l,r,d);
	change1(rs(p),l,r,d);
	merge(p);
}
void change2(int p,int l,int r,int v) {
	if(l(p)>r||r(p)<l||v>=fm1(p)) return;
	if(l<=l(p)&&r(p)<=r&&v>sm(p)) {
		spread_(p,v-fm1(p),v-fm1(p),0,0);
		return;
	}
	spread(p);
	change2(ls(p),l,r,v);
	change2(rs(p),l,r,v);
	merge(p);
}
int ask1(int p,int l,int r) {
	if(l(p)>r||r(p)<l) return 0;
	if(l<=l(p)&&r(p)<=r) return sum(p);
	spread(p);
	return ask1(ls(p),l,r)+ask1(rs(p),l,r);
}
int ask2(int p,int l,int r) {
	if(l(p)>r||r(p)<l) return -inf;
	if(l<=l(p)&&r(p)<=r) return fm1(p);
	spread(p);
	return max(ask2(ls(p),l,r),ask2(rs(p),l,r));
}
int ask3(int p,int l,int r) {
	if(l(p)>r||r(p)<l) return -inf;
	if(l<=l(p)&&r(p)<=r) return fm2(p);
	spread(p);
	return max(ask3(ls(p),l,r),ask3(rs(p),l,r));
}
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i];
	build(1,1,n);
	for(int i=1;i<=m;i++) {
		cin>>opt>>l>>r;
		if(opt==1) {
			cin>>k;
			change1(1,l,r,k);
		}
		if(opt==2) {
			cin>>v;
			change2(1,l,r,v);
		} 
		if(opt==3) cout<<ask1(1,l,r)<<endl;
		if(opt==4) cout<<ask2(1,l,r)<<endl;
		if(opt==5) cout<<ask3(1,l,r)<<endl;
	}
	return 0;
} 

求助QAQ

2022/1/31 16:30
加载中...