前言

spoj需要翻墙注册,比较麻烦,大家就在luogu评测吧

题目大意:

$n$ 个数,$q$ 次操作

操作$0 _ x_ y$把$A_x$ 修改为$y$

操作$1 _ l _r$询问区间$[l, r]$ 的最大子段和

## 思路
###**维护一个区间的$sum,lmax,rmax,max$**
###**就是区间和,左端开头的最大字段和,右端开头的最大字段和和区间内的最大字段和**
###**他们都说转移难,我咋感觉是询问难呢**
###**转移的话**
####**①max 就是右边,左边,和交界处的最大值,取个max**
####**②lmax和rmax类似,就是有两种可能,一种是只在一个孩子内,一种是两个孩子内(完全包含一个孩子)**
####**③sum不必说(其实就是为了求lmax和rmax的)**

查询的话,当然不能加起来啦,如果不连续不就GG了

①如果全部在一个孩子内,直接去查询那个孩子就好

②如果横跨两个孩子的话,还要讨论一下交界处

看着很明白,也许是我太菜了不太会递归吧

我居然能忘记维护sum,也是醉了

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <bitset>
#define ll long long
#define ls rt<<1
#define rs rt<<1|1
using namespace std;
const int maxn = 50007;
const int maxm = 250007;
const int inf = 0x3f3f3f3f; int n, m, a[maxn],tot[maxn];
struct node {
int l, r;
int lk, rk, k, sum;
} e[maxm]; int read() {
int x = 0, f = 1; char s = getchar();
for (; s > '9' || s < '0'; s = getchar()) if (s == '-') f = -1;
for (; s <= '9' && s >= '0'; s = getchar()) x = x * 10 + s - '0';
return x * f;
} int max_2(int a, int b, int c) {
return max(max(a, b), c);
} void pushup(int rt) {
e[rt].k = max_2(e[ls].k, e[rs].k, e[ls].rk + e[rs].lk);
e[rt].lk = max(e[ls].sum + e[rs].lk, e[ls].lk);
e[rt].rk = max(e[ls].rk + e[rs].sum, e[rs].rk);
e[rt].sum= e[ls].sum +e[rs].sum;
} void build(int l, int r, int rt) {
e[rt].l = l, e[rt].r = r, e[rt].sum = tot[r] - tot[l-1];
if (l == r) {
e[rt].k = e[rt].lk = e[rt].rk = a[l];
return;
}
int mid = (l + r) >> 1;
build(l, mid, ls);
build(mid + 1, r, rs);
pushup(rt);
} void update(int L, int k, int rt) {
if (e[rt].l == e[rt].r) {
e[rt].sum=k;
e[rt].k = e[rt].lk = e[rt].rk = k;
return;
}
int mid = (e[rt].l + e[rt].r) >> 1;
if (L <= mid) update(L, k, ls);
else update(L, k, rs);
pushup(rt);
}
void debug() {
printf("debug\n");
printf(" %d\n", e[1].k);
printf(" %d %d\n", e[2].k, e[3].k );
printf(" %d %d %d %d\n", e[4].k, e[5].k, e[6].k, e[7].k );
} node query(int L, int R, int rt) {
if(L<=e[rt].l&&e[rt].r<=R) {
return e[rt];
}
int mid = (e[rt].l + e[rt].r) >> 1;
if(L <= mid && R > mid) {
node x=query(L, R, ls),y=query(L, R, rs);
node tmp={}; tmp.k = max_2(x.k, y.k, x.rk + y.lk);
tmp.lk =max(x.sum + y.lk, x.lk);
tmp.rk =max(x.rk + y.sum, y.rk);
return tmp;
}
if (L <= mid) return query(L, R, ls);
if (R > mid) return query(L, R, rs);
} int main() {
//freopen("in.txt","r",stdin);
n = read();
for (int i = 1; i <= n; ++i) {
a[i] = read();
tot[i]=tot[i-1]+a[i];
}
build(1, n, 1);
m = read();
for (; m--;) {
int tmp = read(), a = read(), b = read();
if (tmp) {
printf("%d\n",max_2(query(a, b, 1).k,query(a,b,1).lk,query(a,b,1).rk) );
} else {
update(a, b, 1);
}
}
//debug();
return 0;
}

最大子段和SP1716GSS3 线段树的更多相关文章

  1. 51nod 1081 子段求和(线段树 | 树状数组 | 前缀和)

    题目链接:子段求和 题意:n个数字序列,m次询问,每次询问从第p个开始L长度序列的子段和为多少. 题解:线段树区间求和 | 树状数组区间求和 线段树: #include <cstdio> ...

  2. 洛谷 P4513 小白逛公园-区间最大子段和-分治+线段树区间合并(单点更新、区间查询)

    P4513 小白逛公园 题目背景 小新经常陪小白去公园玩,也就是所谓的遛狗啦… 题目描述 在小新家附近有一条“公园路”,路的一边从南到北依次排着nn个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩 ...

  3. codevs3981动态最大子段和(线段树)

    3981 动态最大子段和  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond     题目描述 Description 题目还是简单一点好... 有n个数,a ...

  4. codevs 3981 动态最大子段和(线段树)

    题目传送门:codevs 3981 动态最大子段和 题目描述 Description 题目还是简单一点好... 有n个数,a[1]到a[n]. 接下来q次查询,每次动态指定两个数l,r,求a[l]到a ...

  5. BZOJ5142: [Usaco2017 Dec]Haybale Feast 线段树或二分答案

    Description Farmer John is preparing a delicious meal for his cows! In his barn, he has NN haybales ...

  6. BZOJ1135:[POI2009]Lyz(线段树,Hall定理)

    Description 初始时滑冰俱乐部有1到n号的溜冰鞋各k双.已知x号脚的人可以穿x到x+d的溜冰鞋. 有m次操作,每次包含两个数ri,xi代表来了xi个ri号脚的人.xi为负,则代表走了这么多人 ...

  7. SPOJ GSS3-Can you answer these queries III-分治+线段树区间合并

    Can you answer these queries III SPOJ - GSS3 这道题和洛谷的小白逛公园一样的题目. 传送门: 洛谷 P4513 小白逛公园-区间最大子段和-分治+线段树区间 ...

  8. Luogu P2572 [SCOI2010]序列操作 线段树。。

    咕咕了...于是借鉴了小粉兔的做法ORZ... 其实就是维护最大子段和的线段树,但上面又多了一些操作....QWQ 维护8个信息:1/0的个数(sum),左/右边起1/0的最长长度(ls,rs),整段 ...

  9. HDU 6638 - Snowy Smile 线段树区间合并+暴力枚举

    HDU 6638 - Snowy Smile 题意 给你\(n\)个点的坐标\((x,\ y)\)和对应的权值\(w\),让你找到一个矩形,使这个矩阵里面点的权值总和最大. 思路 先离散化纵坐标\(y ...

随机推荐

  1. $("this") $(this) 区别

    1.$("this")是使用标签选择器,查找名为this的标签2.$(this)取出当前对象并转换为jQuery对象3.$(this)是jquery对象,能调用jquery的方法, ...

  2. 【python-opencv】19-Canny边缘检测

    Canny 边缘提取的目标是找到一个最优的边缘检测算法,最优边缘检测的含义是: 好的检测- 算法能够尽可能多地标识出图像中的实际边缘. 好的定位- 标识出的边缘要尽可能与实际图像中的实际边缘尽可能接近 ...

  3. 正则表达式(二):Unicode诸问题上篇(转)

    原文:http://www.infoq.com/cn/news/2011/02/regular-expressions-unicode 关于正则表达式的文档很多,但大部分都是英文的,即便有中文的文档, ...

  4. Memcached与redis的比较--stackoverflow(转)

    原文:http://blog.nosqlfan.com/html/3729.html 这两年Redis火得可以,Redis也常常被当作Memcached的挑战者被提到桌面上来.关于Redis与Memc ...

  5. mysql 数据操作 多表查询 目录

    mysql 数据操作 多表查询 准备 多表连接查询介绍 mysql 数据操作 多表查询 多表连接查询 笛卡尔积 mysql 数据操作 多表查询 多表连接查询 内连接 mysql 数据操作 多表查询 多 ...

  6. sysbench的安装和做性能测试

    sysbench的安装和做性能测试 http://imysql.cn/node/312 sysbench是一个模块化的.跨平台.多线程基准测试工具,主要用于评估测试各种不同系统参数下的数据库负载情况. ...

  7. SQL Server 安装后改动计算机名带来的问题以及解决方法

    USE master GO DECLARE @serverproperty_servername varchar(100), @servername varchar(100) --取得Windows ...

  8. [kx]为什么计算机能读懂 1 和 0 ?

    CPU如何实现运算的? 下面是一个小伙的总结, 从物理电路到逻辑运算到数字电路,一步一步的好理解. 最好能看看那本<编码 隐匿在计算机软硬件背后的语言>的书. 为什么计算机能读懂 1 和 ...

  9. NLP语料库

    文本语料库是一个大型结构化文本的集合 NLTK包含了许多语料库: (1)古滕堡语料库 (2)网络和聊天文本 (3)布朗语料库 (4)路透社语料库 (5)就职演讲语料库 (6)标注文本语料库  词汇列表 ...

  10. jmeter 线程组之间的参数传递(加密接口测试三)

    场景测试中,一次登录后做多个接口的操作,然后登录后的uid需要关联传递给其他接口发送请求的时候使用. 1.在登录接口响应信息中提取uid字段值 1>login请求 -->添加 --> ...