POJ 2750 Potted Flower (单点修改求线段树上最大子序列和)

题目大意:

在一个序列上每次修改一个值,然后求出它的最大的子序列和。

思路分析:

首先我们不考虑不成环的问题。那就是直接求每个区间的最大值就好了。

但是此处成环,那么看一下下面样例。

5

1 -2 -3 4 5

那么你会发现 max = sum - min

也就是和减去最小区间和也可以得到。

所以我们最后要得到的就是两个东西。注意题目中说的不能全部取得。所以还要判断一下max 是不是等于 sum的。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define maxn 100005
#define lson num<<1,s,mid
#define rson num<<1|1,mid+1,e
using namespace std;

struct SegTree
{
    int s,e,sum;
    int lmax,rmax;
    int lmin,rmin;
    int mmin,mmax;
}ret[maxn<<2];

void pushup(int num){
    ret[num].sum=ret[num<<1].sum+ret[num<<1|1].sum;
    ret[num].lmax=max(ret[num<<1].lmax,ret[num<<1].sum+ret[num<<1|1].lmax);
    ret[num].lmin=min(ret[num<<1].lmin,ret[num<<1].sum+ret[num<<1|1].lmin);
    ret[num].rmax=max(ret[num<<1|1].rmax,ret[num<<1|1].sum+ret[num<<1].rmax);
    ret[num].rmin=min(ret[num<<1|1].rmin,ret[num<<1|1].sum+ret[num<<1].rmin);
    ret[num].mmax=max(ret[num<<1].rmax+ret[num<<1|1].lmax,max(ret[num<<1].mmin,ret[num<<1|1].mmin));
    ret[num].mmin=min(ret[num<<1].rmin+ret[num<<1|1].lmin,min(ret[num<<1].mmin,ret[num<<1|1].mmin));
}
void build(int num,int s,int e){
    ret[num].s=s,ret[num].e=e;
    if(s==e){
        scanf("%d",&ret[num].lmax);
        ret[num].sum=ret[num].rmax=ret[num].lmin=ret[num].rmin=ret[num].mmin=ret[num].mmax=ret[num].lmax;
        return;
    }
    int mid=(s+e)>>1;
    build(lson);
    build(rson);
    pushup(num);
}
void update(int num,int s,int e,int pos,int val){
    if(s==e){
        ret[num].sum=ret[num].lmax=ret[num].rmax=ret[num].lmin=ret[num].rmin=ret[num].mmin=ret[num].mmax=val;
        return;
    }
    int mid=(s+e)>>1;
    if(pos<=mid)update(lson,pos,val);
    else update(rson,pos,val);
    pushup(num);
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF){
        build(1,1,n);
        int m;
        scanf("%d",&m);
        while(m--){
            int pos,v;
            scanf("%d%d",&pos,&v);
            update(1,1,n,pos,v);
            if(ret[1].mmax!=ret[1].sum)
            printf("%d\n",max(ret[1].mmax,ret[1].sum-ret[1].mmin));
            else printf("%d\n",ret[1].sum-ret[1].mmin);
        }
    }
    return 0;
}

POJ 2750 Potted Flower (单点修改求线段树上最大子序列和)

时间: 2024-11-14 20:33:39

POJ 2750 Potted Flower (单点修改求线段树上最大子序列和)的相关文章

POJ 2750 Potted Flower (单点改动求线段树上最大子序列和)

题目大意: 在一个序列上每次改动一个值,然后求出它的最大的子序列和. 思路分析: 首先我们不考虑不成环的问题.那就是直接求每一个区间的最大值就好了. 可是此处成环,那么看一下以下例子. 5 1 -2 -3 4 5 那么你会发现 max = sum - min 也就是和减去最小区间和也能够得到. 所以我们最后要得到的就是两个东西.注意题目中说的不能所有取得.所以还要推断一下max 是不是等于 sum的. #include <cstdio> #include <iostream> #i

poj 2750 Potted Flower(线段树区间合并)

http://poj.org/problem?id=2750 有n个数围成一个圈,每次可以将a位置上的数变为b,对每个操作,输出区间的最大连续子段和,连续的子段长度不能超过n. 区间合并问题,因为是求连续子段的和.先把圈从1和n之间断开,变为一条链,先在链上求最长连续的和.这个最长连续的和取左节点最长连续和,右节点最长连续和,左节点从右边数最大连续和加上右节点从左边数最大连续和三者的最大值. 特殊情况就是当区间全为正的时候,最长连续和等于1-n的和,这违背题意,它应该等于区间总和减去区间内最小连

POJ 题目2750 Potted Flower(线段树求环型区间中连续区间的最大和)

Potted Flower Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4470   Accepted: 1698 Description The little cat takes over the management of a new park. There is a large circular statue in the center of the park, surrounded by N pots of f

[hiho 19]单点修改的线段树

问题描述 依然是RMQ问题.过程需要修改某些点的数据. 使用线段树解决. 单点修改的复杂度是O(logn),即树深,只需要修改这个点的祖先节点. 区间查询的复杂度也是O(logn),因为除了第一步可能一分为二外,其他查询若有分解则分解后必然有一个区间是不需要再分解的. #include <stdio.h> #include <algorithm> typedef struct _seg_tree_ { int left, right; int val; _seg_tree_ *ls

【POJ 2750】 Potted Flower(线段树套dp)

[POJ 2750] Potted Flower(线段树套dp) Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4566   Accepted: 1739 Description The little cat takes over the management of a new park. There is a large circular statue in the center of the park, surrou

poj 2750(线段树的动态规划)

Potted Flower Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4186   Accepted: 1581 Description The little cat takes over the management of a new park. There is a large circular statue in the center of the park, surrounded by N pots of f

ZOJ2112 动态区间Kth(单点修改) 线段树+Treap写法

---恢复内容开始--- 题意:给出一个序列和操作次数, 每次操作修改一个位置的数 或者 询问一个区间第k小的数 分析:单点修改可以考虑线段树, 区间排名可以用平衡树 所以线段树+Treap 用一颗线段树将序列划分 每颗Treap中插入的是对应区间的数 在每个数加入时, 顺便将该数插入线段树中包含该位置的那些区间上的Treap即可 单点修改同理, 将所有包含要修改的位置的区间上的Treap都删去原数并插入新数 询问第k小的数:由于询问的区间不一定恰好对应某棵Treap, 不便直接求出名次, 但是

线段树(单点修改,区间求和,区间最大)

(一)线段树 1.E - Lost Cows N (2 <= N <= 8,000) cows have unique brands in the range 1..N. In a spectacular display of poor judgment, they visited the neighborhood 'watering hole' and drank a few too many beers before dinner. When it was time to line up

【算法系列学习】线段树vs树状数组 单点修改,区间查询 [kuangbin带你飞]专题七 线段树 A - 敌兵布阵

https://vjudge.net/contest/66989#problem/A 单点修改,区间查询 方法一:线段树 http://www.cnblogs.com/kuangbin/archive/2011/08/15/2139834.html 1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 #include<cmath> 6 #