线段树最大子段和求调
查看原帖
线段树最大子段和求调
275373
Mayoker楼主2023/6/5 22:20

感觉有可能是Get_ans函数出的问题,但是debug 了好久还是没整出来

#include<iostream>
using namespace std;
const int N=1e5+10,inf=-1e9;
struct node{
	int l,r;
	int pre,mid,low;
	int sum;
}e[N<<2];

int n,m;
int num[N];

void upd(node &p,node &l,node &r){
	p.sum=l.sum+r.sum;
	p.low=max(r.low,r.sum+l.low);
	p.pre=max(l.pre,l.sum+r.pre);
	p.mid=max(l.low+r.pre,max(l.mid,r.mid));
	p.mid=max(p.mid,max(l.mid,r.mid));
	p.mid=max(p.mid,max(p.pre,p.low));
}

void upd(int p){
	upd(e[p],e[p<<1],e[p<<1|1]);
} 

void build(int p,int l,int r){
	e[p]=(node){0,0,0,0,0,0};
	e[p].l=l,e[p].r=r;
	if(l==r){
		e[p].low=num[l];
		e[p].mid=num[l];
		e[p].pre=num[l];
		e[p].sum=num[l];
	}
	else{
		int mid=l+r>>1;
		build(p<<1,l,mid);
		build(p<<1|1,mid+1,r);
		upd(p);
	}
}

node ask(int p,int l,int r){
	if(l>r) return (node){0,0,0,0,0,0};
	else if(e[p].l>=l&&e[p].r<=r){
		return e[p];
	}
	else{
		int mid=e[p].l+e[p].r>>1;
		node res,t1,t2;
		res=(node){0,0,0,0,0,0};
		int d1,d2;
		d1=d2=0;
		if(l<=mid) t1=ask(p<<1,l,r),d1=1;
		if(r>mid) t2=ask(p<<1|1,l,r),d2=1;
		if(d1&&d2) upd(res,t1,t2);
		else if(d1) res=t1;
		else if(d2) res=t2;
		return res;
	}
}

int get_ans(int a,int b,int c,int d){
	if(c>b) 
	return ask(1,a,b).low+ask(1,b+1,c-1).sum+ask(1,c,d).pre;
	else if(a==c&&d==b) return ask(1,a,b).mid;
	else return max(max(ask(1,c,b).mid,
	ask(1,a,c).low+ask(1,c+1,b-1).sum+ask(1,b,d).pre),
	max(ask(1,a,c).low+ask(1,c,d).pre-num[c],
	ask(1,b,d).pre+ask(1,a,b).low)-num[b]);
}

void solve(){
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>num[i];
	build(1,1,n);
	cin>>m;
	int l1,r1,l2,r2;
	while(m--){
		cin>>l1>>r1>>l2>>r2;
		cout<<get_ans(l1,r1,l2,r2)<<'\n';
	}
	return ;
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	
	int t;cin>>t;
	while(t--){
		solve();
	}
	
	return 0;
}
2023/6/5 22:20
加载中...