POJ 2750 Potted Flower

题链

我们统计一波区间的最大最小值。

answer=max(sum-区间最小值,区间最大值);

特判一点,当最小值>0时,那么我们把最小值减去,因为我们不能选一个圈。

一遍过样例什么的最虚了。

#include<cstdio>
#include<iostream>
#include<algorithm>
#define sight(x) ('0'<=x&&x<='9')
#define N 100007
#define TN (N<<2)|N
using namespace std;
inline void read(int &x){
    static int b;static char c;
    for (c=getchar(),b=1;!sight(c);c=getchar())if (c=='-') b=-1;
    for (x=0;sight(c);c=getchar()) x=x*10+c-48;x*=b;
}
int x,y,q,n,a[N],Sum,mm[TN],ma[TN],mi[TN],sum[TN],lmax[TN],rmax[TN],lmin[TN],rmin[TN];
#define Mid (l+r>>1)
inline void up(int No){
    mm[No]=min(mm[No<<1],mm[No<<1|1]);
    ma[No]=max(ma[No<<1],ma[No<<1|1]);
    mi[No]=min(mi[No<<1],mi[No<<1|1]);
    ma[No]=max(ma[No],rmax[No<<1]+lmax[No<<1|1]);
    mi[No]=min(mi[No],rmin[No<<1]+lmin[No<<1|1]);
    sum[No]=sum[No<<1]+sum[No<<1|1];
    lmax[No]=max(lmax[No<<1],sum[No<<1]+lmax[No<<1|1]);
    rmax[No]=max(rmax[No<<1|1],sum[No<<1|1]+rmax[No<<1]);
    lmin[No]=min(lmin[No<<1],sum[No<<1]+lmin[No<<1|1]);
    rmin[No]=min(rmin[No<<1|1],sum[No<<1|1]+rmin[No<<1]);
}
void build (int No,int l,int r){
    if (l==r) {
        ma[No]=rmax[No]=lmax[No]=a[l];
        mi[No]=rmin[No]=lmin[No]=a[l];
        sum[No]=mm[No]=a[l];
        return;
    }
    build(No<<1,l,Mid); build(No<<1|1,Mid+1,r);
    up(No); 
}
void change(int No,int l,int r,int x){
    if (l==r) {
        ma[No]=rmax[No]=lmax[No]=a[l];
        mi[No]=rmin[No]=lmin[No]=a[l];
        sum[No]=mm[No]=a[l];
        return;
    }
    if (x<=Mid) change(No<<1,l,Mid,x);
    else change(No<<1|1,Mid+1,r,x); 
    up(No);
}
inline void out() {
    if (mm[1]>0) { printf("%d\n",Sum-mm[1]);return;}
    printf("%d\n",max(Sum-mi[1],ma[1]));
}
int main () {
    read(n);
    for (int i=1;i<=n;i++) {read(a[i]); Sum+=a[i];}
    build(1,1,n); read(q);
    while (q--) {
        read(x);read(y);
        Sum-=a[x]; Sum+=y; a[x]=y;
        change(1,1,n,x);
        out();
    }
}

 

posted @ 2018-01-27 10:37  泪寒之雪  阅读(163)  评论(0编辑  收藏  举报