http://poj.org/problem?id=2570
思路
- 最大环上字段和=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;
}