poj2750Potted Flower (线段树)

时间:2023-03-09 17:35:46
poj2750Potted Flower (线段树)

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

之前做过类似的题 把一段的左连续最大、最小 右连续最大及最小及中间的连续更新出 就可以算出这段最大的连续和

注意不能全部加上 加上一特判 如果最大和是全部数的和就减去这段最小的和

 #include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
using namespace std;
#define N 100010
struct node
{
int va,lmax,rmin,lmin,rmax,smax,smin;
}p[N<<];
void pushup(int w)
{
p[w].va = p[w<<].va+p[w<<|].va;
p[w].lmax = max(p[w<<].lmax,p[w<<].va+p[w<<|].lmax);
p[w].lmin = min(p[w<<].lmin,p[w<<].va+p[w<<|].lmin);
p[w].rmax = max(p[w<<|].rmax,p[w<<|].va+p[w<<].rmax);
p[w].rmin = min(p[w<<|].rmin,p[w<<|].va+p[w<<].rmin);
p[w].smax = max(max(p[w].lmax,p[w].rmax),max(p[w<<].smax,p[w<<|].smax));
p[w].smax = max(p[w].smax,p[w<<].rmax+p[w<<|].lmax);
p[w].smin = min(min(p[w].lmin,p[w].rmin),min(p[w<<].smin,p[w<<|].smin));
p[w].smin = min(p[w].smin,p[w<<].rmin+p[w<<|].lmin);
}
void build(int l,int r,int w)
{
if(l==r)
{
scanf("%d",&p[w].va);
p[w].lmax=p[w].lmin=p[w].rmax=p[w].rmin=p[w].smax=p[w].smin=p[w].va;
return ;
}
int m = (l+r)>>;
build(l,m,w<<);
build(m+,r,w<<|);
pushup(w);
}
void update(int pp,int d,int l,int r,int w)
{
if(l==r)
{
p[w].va = d;
p[w].lmax=p[w].lmin=p[w].rmax=p[w].rmin=p[w].smax=p[w].smin=p[w].va;
return ;
}
int m = (l+r)>>;
if(pp<=m)
update(pp,d,l,m,w<<);
else
update(pp,d,m+,r,w<<|);
pushup(w);
}
int main()
{
int n,m,a,b,i;
while(cin>>n)
{
build(,n,);
cin>>m;
while(m--)
{
scanf("%d%d",&a,&b);
update(a,b,,n,);
if(p[].smax==p[].va)
cout<<p[].smax-p[].smin<<endl;
else
cout<<max(p[].smax,p[].va-p[].smin)<<endl;
}
}
return ;
}