poj2570

http://poj.org/problem?id=2570

思路

  1. 最大环上字段和=max(序列最大字段和,sum-序列最小字段和)

code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
inline int read() {
	int x=0,f=1;char ch=' ';
	while(ch<'0'||ch>'9'){	if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){	x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
const int N=100100;
struct node
{
	int maxl,maxr,max;int sum;
	int minl,minr,min;
}t[N<<2];
int a[N];
void update(int rt)
{
	t[rt].sum=t[rt<<1].sum+t[rt<<1|1].sum;
	
	t[rt].max=max(t[rt<<1].max,t[rt<<1|1].max);
	t[rt].max=max(t[rt<<1].maxr+t[rt<<1|1].maxl,t[rt].max);
	
	t[rt].maxl=max(t[rt<<1].maxl,t[rt<<1].sum+t[rt<<1|1].maxl);
	t[rt].maxr=max(t[rt<<1|1].maxr,t[rt<<1|1].sum+t[rt<<1].maxr);
	
	t[rt].min=min(t[rt<<1].min,t[rt<<1|1].min);
	t[rt].min=min(t[rt].min,t[rt<<1].minr+t[rt<<1|1].minl);
	
	t[rt].minl=min(t[rt<<1].minl,t[rt<<1].sum+t[rt<<1|1].minl);
	t[rt].minr=min(t[rt<<1|1].minr,t[rt<<1|1].sum+t[rt<<1].minr);
}
void build(int rt,int l,int r)
{
	if(l==r)
	{
		t[rt].max=t[rt].maxl=t[rt].maxr=a[l];
		t[rt].min=t[rt].minl=t[rt].minr=a[l];
		t[rt].sum=a[l];
		return ;
	}
	else
	{
		t[rt].max=t[rt].maxl=t[rt].maxr=-inf;
		t[rt].min=t[rt].minl=t[rt].minr=inf;
		t[rt].sum=0;
	}
	int mid=l+r>>1;
	build(rt<<1,l,mid);
	build(rt<<1|1,mid+1,r);
	update(rt);
}
void modify(int rt,int l,int r,int p,int x)
{
	if(l==r)
	{
		t[rt].max=t[rt].maxl=t[rt].maxr=x;
		t[rt].min=t[rt].minl=t[rt].minr=x;
		t[rt].sum=x;
		return ;
	}
	int mid=l+r >> 1;
	if(p<=mid) modify(rt<<1,l,mid,p,x);
	else modify(rt<<1|1,mid+1,r,p,x);
	update(rt);
}
int main()
{
	int n;
	n=read();
	int i,j;
	for(i=1;i<=n;i++) a[i]=read();
	build(1,1,n);
	int m=read();
	while(m--)
	{
		int p=read(),x=read();
		modify(1,1,n,p,x);
		int ans=0;
		if(t[1].max==t[1].sum) ans=t[1].sum-t[1].min; 
		else ans=max(t[1].max,t[1].sum-t[1].min);
		cout<<ans<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42110318/article/details/86669590