GSS3 - Can you answer these queries III
题意翻译
nnn 个数, qqq 次操作
操作0 x y把 AxA_xAx 修改为 yyy
操作1 l r询问区间 [l,r][l, r][l,r] 的最大子段和
感谢 @Edgration 提供的翻译
题目描述
You are given a sequence A of N (N <= 50000) integers between -10000 and 10000. On this sequence you have to apply M (M <= 50000) operations:
modify the i-th element in the sequence or for given x y print max{Ai + Ai+1 + .. + Aj | x<=i<=j<=y }.
输入输出格式
输入格式:
The first line of input contains an integer N. The following line contains N integers, representing the sequence A1..AN.
The third line contains an integer M. The next M lines contain the operations in following form:
0 x y: modify Ax into y (|y|<=10000).
1 x y: print max{Ai + Ai+1 + .. + Aj | x<=i<=j<=y }.
输出格式:
For each query, print an integer as the problem required.
输入输出样例
4
1 2 3 4
4
1 1 3
0 3 -3
1 2 4
1 3 3
6
4
-3 提交地址 : luogu SP1716
spoj; 分析:
线段树水题; 用线段树维护四个值 : 这一区间的最大子段和, 这一区间的从最左端开始的最大子段和, 从右端开始的最大子段和,还有这一段的和;
怎么维护?
t[o].sum = t[ls(o)].sum + t[rs(o)].sum;
t[o].lsum = max(t[ls(o)].lsum, t[ls(o)].sum + t[rs(o)].lsum);
t[o].rsum = max(t[rs(o)].rsum, t[rs(o)].sum + t[ls(o)].rsum);
t[o].dat = max(t[ls(o)].rsum + t[rs(o)].lsum, max(t[ls(o)].dat, t[rs(o)].dat));
就解释一个:你左端开始的最大子段和一定是你左二子的左端点开始的最大子段和, 还有左二子全选加上右儿子的左端开始的最大子段和;
其他的都大同小异;
一样的按照普通线段树写;
主要讲讲查询操作;
因为我们要找一个连续的序列,而不是每个dat取max;
所以我们要维护一个前缀和qzh;
因为我们维护的是前缀和, 所以每次可以用 qzh+t[o].lsum 和 t[o].dat 取max来更新ans;
然后我们再改变qzh的值 在 qzh + t[o].sum 和 t[o].rsum中取max;
代码奉上:
//zZhBr
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
#define int long long inline int read()
{
int res=;bool flag=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')flag=;ch=getchar();};
while(isdigit(ch)){res=(res<<)+(res<<)+(ch-'');ch=getchar();}
return flag?-res:res;
} const int N = ; int n, a[N], m;
int ans, qzh; struct Segment
{
int ls, rs;
int l, r;
int sum;
int lsum, rsum;
int dat;
}t[N<<];
int cnt = ;
int root;
#define ls(x) t[x].ls
#define rs(x) t[x].rs inline void pushup(int o)
{
t[o].l = t[ls(o)].l, t[o].r = t[rs(o)].r;
t[o].sum = t[ls(o)].sum + t[rs(o)].sum;
t[o].lsum = max(t[ls(o)].lsum, t[ls(o)].sum + t[rs(o)].lsum);
t[o].rsum = max(t[rs(o)].rsum, t[rs(o)].sum + t[ls(o)].rsum);
t[o].dat = max(t[ls(o)].rsum + t[rs(o)].lsum, max(t[ls(o)].dat, t[rs(o)].dat));
} inline void build(int l, int r, int o)
{
if (l == r)
{
t[o].sum = a[l];
t[o].lsum = a[l];
t[o].rsum = a[l];
t[o].dat = a[l];
t[o].l = t[o].r = l;
return;
} int mid = l + r >> ;
t[o].ls = cnt++;
t[o].rs = cnt++;
build(l, mid, ls(o));
build(mid + , r, rs(o));
pushup(o);
} inline void change(int o, int x, int v)
{
if (t[o].l == t[o].r)
{
t[o].sum = v;
t[o].dat = v;
t[o].lsum = t[o].rsum = v;
return;
} int mid = t[o].l + t[o].r >> ; if (x <= mid) change(ls(o), x, v);
else change(rs(o), x, v);
pushup(o);
} inline void query(int o, int li, int ri)
{
if (li <= t[o].l and ri >= t[o].r)
{
ans = max(ans, max(qzh + t[o].lsum, t[o].dat));
qzh = max(qzh + t[o].sum, t[o].rsum);
return;
}
int res = ;
int mid = t[o].r + t[o].l >> ;
if (li <= mid) query(ls(o), li, ri);
if (ri > mid) query(rs(o), li, ri);
} signed main()
{
n = read();
for (register int i = ; i <= n ; i ++) a[i] = read();
m = read();
root = cnt++;
build(, n, root); while (m--)
{
int opt = read();
int x = read(), y = read(); if (opt == )
{
change(root, x, y);
}
else
{
ans = -1e9, qzh = -1e9;
query(root, x, y);
printf("%lld\n", ans);
}
} return ; }
GSS3 - Can you answer these queries III的更多相关文章
- SPOJ GSS3 Can you answer these queries III[线段树]
SPOJ - GSS3 Can you answer these queries III Description You are given a sequence A of N (N <= 50 ...
- 数据结构(线段树):SPOJ GSS3 - Can you answer these queries III
GSS3 - Can you answer these queries III You are given a sequence A of N (N <= 50000) integers bet ...
- 线段树 SP1716 GSS3 - Can you answer these queries III
SP1716 GSS3 - Can you answer these queries III 题意翻译 n 个数,q 次操作 操作0 x y把A_xAx 修改为yy 操作1 l r询问区间[l, r] ...
- SP1716 GSS3 - Can you answer these queries III(单点修改,区间最大子段和)
题意翻译 nnn 个数, qqq 次操作 操作0 x y把 AxA_xAx 修改为 yyy 操作1 l r询问区间 [l,r][l, r][l,r] 的最大子段和 题目描述 You are give ...
- SP1716 GSS3 - Can you answer these queries III - 动态dp,线段树
GSS3 Description 动态维护最大子段和,支持单点修改. Solution 设 \(f[i]\) 表示以 \(i\) 为结尾的最大子段和, \(g[i]\) 表示 \(1 \sim i\) ...
- SPOJ GSS3 Can you answer these queries III
Time Limit: 330MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Description You are g ...
- spoj 1557 GSS3 - Can you answer these queries III 线段树
题目链接 给出n个数, 2种操作, 一种是将第x个数改为y, 第二种是询问区间[x,y]内的最大连续子区间. 开4个数组, 一个是区间和, 一个是区间最大值, 一个是后缀的最大值, 一个是前缀的最大值 ...
- SP1716 GSS3 - Can you answer these queries III
题面 题解 相信大家写过的传统做法像这样:(这段代码蒯自Karry5307的题解) struct SegmentTree{ ll l,r,prefix,suffix,sum,maxn; }; //.. ...
- SPOJ GSS3 Can you answer these queries III ——线段树
[题目分析] GSS1的基础上增加修改操作. 同理线段树即可,多写一个函数就好了. [代码] #include <cstdio> #include <cstring> #inc ...
- [SPOJ1716] GSS3 - Can you answer these queries III
线段树操作. 维护一个区间最大连续子段和,左最大连续子段和,右最大连续子段和即可. 最后不知道怎么搞,query的时候返回了个结构体. #include <cstdio> #include ...
随机推荐
- Winform中实现ZedGraph的多条Y轴(附源码下载)
场景 Winforn中设置ZedGraph曲线图的属性.坐标轴属性.刻度属性: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10 ...
- 【学习笔记】python3核心技术与实践--开篇词
python的应用和流行程度: Python 可以运用在数据处理.Web 开发.人工智能等多个领域,它的语言简洁.开发效率高.可移植性强,并且可以和其他编程语言(比如 C++)轻松无缝衔接.现如今,不 ...
- 深入理解Three.js中透视投影照相机PerspectiveCamera
前言 在开始正式讲解透视摄像机前,我们先来理理three.js建模的流程.我们在开始创建一个模型的时候,首先需要创建我们模型需要的物体,这个物体可以是three.js中已经为我们封装好的,比如正方体, ...
- 【python】requests模块初探(一)
一.写在前面 Requests 是用Python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库.它比 urllib 更加方便,可以节约我们大量的工作,完 ...
- [AWS] EC2 & GPU
Amazon Elastic Compute Cloud (Amazon EC2) EC 2的使用 机型的选择 经验谈 Ref: Amazon EC2 实例类型 实践派 搭建网站:MediaWiki ...
- C++基础之IO类
下面是IO类的继承关系: ifstream和istringstream都继承自istream.因此,我们可以在传递istream对象的地方传递ifstream和istringstream. 例如:对i ...
- Channel使用技巧
前言 Go协程一般使用channel(通道)通信从而协调/同步他们的工作.合理利用Go协程和channel能帮助我们大大提高程序的性能.本文将介绍一些使用channel的场景及技巧 场景一,使用cha ...
- 【linux】【Python】python2.7安装pip9.0.1
Centos7系统默认自带python2.7,但是没有安装pip. [root@localhost docker-elk]# python -V Python 2.7.5 [root@localhos ...
- odoo Botton标签属性详解
按钮属性 1)icon 按钮图标名,可用的按钮图标在 addons/web/static/src/img/下. 2)string 按钮的显示文字 3)type 动作执行类型.可能值是:workflow ...
- 用git提交新项目到github
1.(先进入项目文件夹)通过命令 git init 把这个目录变成git可以管理的仓库 git init 2.把文件添加到版本库中,使用命令 git add .添加到暂存区里面去,不要忘记后面的小数点 ...