题目链接:点击打开链接

题目大意:给出n个数排成一个环。求环的最大连续子序列,不能是总序列

建一个线段树来求最大子序列假设仅仅是一个序列。那么求最大连续子序列非常easy,可是假设是一个环,那就要考虑断点的问题,由于结果可能是由左边一部分+右边一部分,这种结果用线段树没法统计到,所以须要转换一下:

求最大连续子序列 = 总和 - 最小连续子序列

那么题目就非常easy了,要统计出每一段的最大连续子序列,最小连续子序列和总和。

sum[rt] = sum[rt<<1] + sum[rt<<1|1] ;

max1[rt] = max( max(max1[rt<<1],max1[rt<<1|1]),rmax1[rt<<1]+lmax1[rt<<1|1] ) ; 最大连续子序列

min1[rt] = min( min(min1[rt<<1],min1[rt<<1|1]),rmin1[rt<<1]+lmin1[rt<<1|1] ) ; 最小连续子序列

lmax1[rt] = max(lmax1[rt<<1],sum[rt<<1]+lmax1[rt<<1|1]) ; 以左側开头的最大子序列

lmin1[rt] = min(lmin1[rt<<1],sum[rt<<1]+lmin1[rt<<1|1]) ; 以左側开头的最小子序列

rmax1[rt] = max(rmax1[rt<<1|1],sum[rt<<1|1]+rmax1[rt<<1]) ; 以右側开头的最大子序列

rmin1[rt] = min(rmin1[rt<<1|1],sum[rt<<1|1]+rmin1[rt<<1]) ; 以右側开头的最小子序列

有由于不能是所有的序列,那么能够分开考虑,假设全都是整数,最大连续子序列是总和,那么结果应该是总和-最小连续子序列,假设全是负数。那么结果应该是最大连续子序列,其它的为 max(max1[1],sum[1]-min1[1]))

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
#define root 1,n,1
#define int_rt int l,int r,int rt
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
int cl[1000000] , sum[1000000] ;
int max1[1000000] , min1[1000000] ;
int lmax1[1000000] , lmin1[1000000] ;
int rmax1[1000000] , rmin1[1000000] ;
void push_up(int rt) {
sum[rt] = sum[rt<<1] + sum[rt<<1|1] ;
max1[rt] = max( max(max1[rt<<1],max1[rt<<1|1]),rmax1[rt<<1]+lmax1[rt<<1|1] ) ;
min1[rt] = min( min(min1[rt<<1],min1[rt<<1|1]),rmin1[rt<<1]+lmin1[rt<<1|1] ) ;
lmax1[rt] = max(lmax1[rt<<1],sum[rt<<1]+lmax1[rt<<1|1]) ;
lmin1[rt] = min(lmin1[rt<<1],sum[rt<<1]+lmin1[rt<<1|1]) ;
rmax1[rt] = max(rmax1[rt<<1|1],sum[rt<<1|1]+rmax1[rt<<1]) ;
rmin1[rt] = min(rmin1[rt<<1|1],sum[rt<<1|1]+rmin1[rt<<1]) ;
}
void creat(int_rt) {
if( l == r ) {
scanf("%d", &cl[rt]) ;
sum[rt] = max1[rt] = min1[rt] = lmax1[rt] = lmin1[rt] = rmax1[rt] = rmin1[rt] = cl[rt] ;
return ;
}
creat(lson) ;
creat(rson) ;
push_up(rt) ;
}
void update(int k,int s,int_rt) {
if( l == r ) {
cl[rt] = s ;
sum[rt] = max1[rt] = min1[rt] = lmax1[rt] = lmin1[rt] = rmax1[rt] = rmin1[rt] = cl[rt] ;
return ;
}
if( (l+r)/2 >= k )
update(k,s,lson) ;
else
update(k,s,rson) ;
push_up(rt) ;
}
int main() {
int n , m , i , k , s ;
while( scanf("%d", &n) != EOF ) {
creat(root) ;
scanf("%d", &m) ;
while( m-- ) {
scanf("%d %d", &k, &s) ;
update(k,s,root) ;
if( max1[1] == sum[1] )
printf("%d\n", sum[1]-min1[1]) ;
else if( min1[1] == sum[1] )
printf("%d\n", max1[1]) ;
else
printf("%d\n", max(max1[1],sum[1]-min1[1])) ;
}
}
return 0 ;
}

poj2750--Potted Flower(线段树)的更多相关文章

  1. POJ 2750 Potted Flower (线段树区间合并)

    开始懵逼找不到解法,看了网上大牛们的题解才发现是区间合并...  给你n个数形成一个数列环,然后每次进行一个点的修改,并输出这个数列的最大区间和(注意是环,并且区间最大只有n-1个数) 其实只需要维护 ...

  2. POJ.2750.Potted Flower(线段树 最大环状子段和)

    题目链接 /* 13904K 532ms 最大 环状 子段和有两种情况,比如对于a1,a2,a3,a4,a5 一是两个端点都取,如a4,a5,a1,a2,那就是所有数的和减去不选的,即可以计算总和减最 ...

  3. POJ 2750 Potted Flower(线段树+dp)

    题目链接 虽然是看的别的人思路,但是做出来还是挺高兴的. 首先求环上最大字段和,而且不能是含有全部元素.本来我的想法是n个元素变为2*n个元素那样做的,这样并不好弄.实际可以求出最小值,总和-最小,就 ...

  4. Potted Flower(线段树+dp)

    http://poj.org/problem?id=2750 题意:在一个圈中取若干个相邻的数,求他们的最大序列和.不能够同时取所有的数. 看了一篇解题报告写的很详细..http://blog.csd ...

  5. [POJ2750]Potted Flower

    Description The little cat takes over the management of a new park. There is a large circular statue ...

  6. poj2750Potted Flower (线段树)

    http://poj.org/problem?id=2750 之前做过类似的题 把一段的左连续最大.最小 右连续最大及最小及中间的连续更新出 就可以算出这段最大的连续和 注意不能全部加上 加上一特判 ...

  7. poj2750 线段树 +DP Potted Flower

    问题描述:给定一个环形序列,进行在线操作,每次修改一个元素,输出环上的最大连续子列的和,但不能是完全序列. 算法:把环从一个地方,切断拉成一条直线,用线段树记录当前区间的非空最大子列和当前区间的非空最 ...

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

    [POJ 2750] Potted Flower(线段树套dp) Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4566   ...

  9. POJ 2750 Potted Flower(线段树的区间合并)

    点我看题目链接 题意 : 很多花盆组成的圆圈,每个花盆都有一个值,给你两个数a,b代表a位置原来的数换成b,然后让你从圈里找出连续的各花盆之和,要求最大的. 思路 :这个题比较那啥,差不多可以用DP的 ...

随机推荐

  1. Integer应该用==还是equals

    问题引出:“Integer应该用==还是equals” 讨论这个问题之前我们先放一段代码 public static void main(String[] args) { Integer a1 = 2 ...

  2. xx网络--工具集合

    -- D:\workspace\bajie_projram\BJ.srfcb\BJ.srfcb\BJ.srfcb 8jielicai_New\App_Code\common\pg.cs---GetHt ...

  3. Linux学习教程

    前言 “Linux?听说是一个操作系统,好用吗?” “我也不知道呀,和windows有什么区别?我能在Linux上玩LOL吗” “别提了,我用过Linux,就是黑乎乎一个屏幕,鼠标也不能用,不停地的敲 ...

  4. 跳出双重for循环的案例__________跳出当前循环(continue out)

    package com.etc.operator; public class demo { public static void main(String[] args) { // break out; ...

  5. C#之MD5加密

    C#实现MD5加密 方法一 首先,先简单介绍一下MD5 MD5的全称是message-digest algorithm 5(信息-摘要算法,在90年代初由mit laboratory for comp ...

  6. windbg将调试信息保存到文本文件

    在跟踪一些出现频率较低的问题时,有时候需要长时间调试,但是在在输出信息太多时可能前面的日志会被清空,为避免这种情况,可以将输出日志记录到文本文件以备查看. 1. 可以在启动时直接用带 -logo的命令 ...

  7. 分布式文件管理系统MooseFS在centOS 7中的安装

    首先,MooseFS是做什么的在这边不做具体详述,这边主要记录一下我在自己部署MooseFS中遇到的问题和步骤(大部分参考的其他博客或者资料) 首先是准备资源,MooseFS的最新安装包可以去官网下载 ...

  8. 经典实用SQL Server语句大全总结(一)

    简要介绍基础语句:1.说明:创建数据库CREATE DATABASE database-name2.说明:删除数据库drop database dbname3.说明:备份sql server--- 创 ...

  9. Windows Live Writer 历史Blog修改的功能

    其实 WLW 有历史Blog修改的功能,我只是一直没有找到,就在打开“最近发布的日志”里面, 位于屏幕的右侧“打开”列表下. 最近发现记忆力越来越差了,BLOG看来是必须的了.

  10. AFNetworking源码解析-https证书相关

    本篇说说安全相关的AFSecurityPolicy模块,AFSecurityPolicy用于验证HTTPS请求的证书,先来看看HTTPS的原理和证书相关的几个问题. HTTPS HTTPS连接建立过程 ...