社区讨论

9pts求助,玄关

P4513小白逛公园参与者 3已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@loi7kgz6
此快照首次捕获于
2023/11/03 14:02
2 年前
此快照最后确认于
2023/11/03 16:55
2 年前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+1000;
#define ll long long
ll n,m;
ll op,l,r;
struct node{
	ll tot;
	ll max_back;
	ll max_front;
	ll max_tot;
}tree[N<<2];
ll number[N];
void update(ll num){
	tree[num].tot=tree[num<<1].tot+tree[num<<1|1].tot;
	tree[num].max_front=max({tree[num].max_front , tree[num<<1].max_front , tree[num<<1].tot+tree[num<<1|1].max_front});
	tree[num].max_back=max({tree[num].max_back , tree[num<<1|1].max_back , tree[num<<1|1].tot+tree[num<<1].max_back});
	tree[num].max_tot=max({tree[num].max_tot , tree[num<<1].max_back+tree[num<<1|1].max_front , tree[num<<1].max_tot , tree[num<<1|1].max_tot});
	return;
}
void build(ll l,ll r,ll num){
	if(l==r){
		tree[num].tot=number[l];
		tree[num].max_tot=number[l];
		tree[num].max_front=tree[num].max_back=max((ll)0,number[l]);
		return;
	}
	ll mid=(l+r)/2;
	build(l,mid,num<<1);
	build(mid+1,r,num<<1|1);
	update(num);
	return;
}
void change_num(ll pos,ll l,ll r,ll num,ll change_number){
//	cout<<pos<<" "<<change_number<<' '<<l<<' '<<r<<' '<<num<<'\n';
	if(l==r&&l==pos){
		tree[num].tot=change_number;
		tree[num].max_front=tree[num].max_back=max((ll)0,change_number);
		tree[num].max_tot=change_number;
		return;
	}
	if(l>pos||r<pos)return;
	ll mid=(l+r)/2;
	if(mid>=pos)change_num(pos,l,mid,num<<1,change_number);
	else change_num(pos,mid+1,r,num<<1|1,change_number);
	update(num);
	return;
}
ll find_tot(ll want_l,ll want_r,ll l,ll r,ll num){
	if(want_l<=l&&want_r>=r){
//		cout<<want_l<<" "<<want_r<<' '<<l<<' '<<r<<' '<<num<<'\n';
//		cout<<tree[num].max_tot<<'\n';
		return tree[num].max_tot;
	}
	ll ans=-1e9;
	ll mid=(l+r)/2;
	if(want_l<=mid)ans=max(ans,find_tot(want_l,want_r,l,mid,num<<1));
	if(want_r>mid)ans=max(ans,find_tot(want_l,want_r,mid+1,r,num<<1|1));
	update(num);
	return ans;
}
int  main(){
	scanf("%lld %lld",&n,&m);
	for(ll i=1;i<=n;i++)scanf("%lld",&number[i]);
	build(1,n,1);
	for(ll i=1;i<=m;i++){
		scanf("%lld %lld %lld",&op,&l,&r);
		if(op==1){
			if(l>r)swap(l,r);
			printf("%lld\n",find_tot(l,r,1,n,1));
		}
		else{
			change_num(l,1,n,1,r);
		}
	}
	return 0;
}
只对了第一个点。

回复

2 条回复,欢迎继续交流。

正在加载回复...