Can you answer these queries III

题目:洛谷  SPOJ

【题目描述】

给定长度为N的数列A,以及M条指令,每条指令可能是以下两种之一:

1.“0 x y”,把A[x]改成y;

2.“1 x y”,查询区间[x,y]中的最大连续子段和。

【输入格式】

第一行,N;

第二行,N个数,即A[1]...A[N];

第三行,M;

第4至第M+3行,每行三个整数,分别表示“0或1”,x,y,即指令。

【输出格式】

i行,i表示“1 x y”的数量,每行1个整数,即指令2的答案。

【数据规模】

N,M<=50000。

解析

查询区间最大连续子段和,显然可以用线段树维护序列。

先分析一下,在线段树中,对于查询的每个区间[x,y],会有以下两种情况:

1、如图所示,区间刚好在一个子树中,只需查询该子树的区间最大连续子段和即可;

2、如图所示,区间一部分在左子树中,另一部分在右子树中,对于这种情况,该区间的最大连续子段和为左子树的最大后缀和加上右子树的最大前缀和。

考虑完所有情况后,只需套上线段树模板再稍作修改即可。

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
using namespace std;
struct rec{
int l,r,maxn,lmax,rmax,sum;//lmax最大前缀和,rmax最大后缀和
}t[];
int n,m,a[];
void build(int p,int l,int r)
{
t[p].l=l,t[p].r=r;
if(l==r)
{
t[p].sum=t[p].lmax=t[p].rmax=t[p].maxn=a[l];
return ;
}
int mid=(l+r)/;
build(p*,l,mid);
build(p*+,mid+,r);
t[p].sum=t[p*].sum+t[p*+].sum;
t[p].lmax=max(t[p*].lmax,t[p*].sum+t[p*+].lmax);
t[p].rmax=max(t[p*+].rmax,t[p*+].sum+t[p*].rmax);
t[p].maxn=max(t[p*].rmax+t[p*+].lmax,max(t[p*].maxn,t[p*+].maxn));
return ;
}
void change(int p,int x,int v)
{
if(t[p].l==t[p].r)
{
t[p].sum=t[p].rmax=t[p].lmax=t[p].maxn=v;
return ;
}
int mid=(t[p].l+t[p].r)/;
if(x<=mid) change(p*,x,v);
else change(p*+,x,v);
t[p].sum=t[p*].sum+t[p*+].sum;
t[p].lmax=max(t[p*].lmax,t[p*].sum+t[p*+].lmax);
t[p].rmax=max(t[p*+].rmax,t[p*+].sum+t[p*].rmax);
t[p].maxn=max(t[p*].rmax+t[p*+].lmax,max(t[p*].maxn,t[p*+].maxn));
}
rec ask(int p,int l,int r)
{
if(l<=t[p].l&&r>=t[p].r) return t[p];
rec a,b,ans;
a.sum=a.lmax=a.rmax=a.maxn=b.sum=b.lmax=b.rmax=b.maxn=0xcfcfcfcf;
ans.sum=;
int mid=(t[p].l+t[p].r)/;
if(l<=mid)
{
a=ask(p*,l,r);
ans.sum+=a.sum;
}
if(r>mid)
{
b=ask(p*+,l,r);
ans.sum+=b.sum;
}
ans.maxn=max(max(a.maxn,b.maxn),a.rmax+b.lmax); //注意负数
ans.lmax=max(a.lmax,a.sum+b.lmax);
ans.rmax=max(b.rmax,b.sum+a.rmax);
if(l>mid) ans.lmax=max(ans.lmax,b.lmax);
if(r<=mid) ans.rmax=max(ans.rmax,a.rmax);
//分类讨论
return ans;
}
int main()
{
int c,l,r;
cin>>n;
for(int i=;i<=n;i++) cin>>a[i];
build(,,n);
cin>>m;
for(int i=;i<=m;i++)
{
cin>>c>>l>>r;
if(c==) change(,l,r);
else cout<<ask(,l,r).maxn<<endl;
}
return ;
}

Can you answer these queries III的更多相关文章

  1. 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 ...

  2. GSS3 SPOJ 1716. Can you answer these queries III gss1的变形

    gss2调了一下午,至今还在wa... 我的做法是:对于询问按右区间排序,利用splay记录最右的位置.对于重复出现的,在splay中删掉之前出现的位置所在的节点,然后在splay中插入新的节点.对于 ...

  3. 数据结构(线段树):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 ...

  4. 线段树 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] ...

  5. 「 SPOJ GSS3 」 Can you answer these queries III

    # 题目大意 GSS3 - Can you answer these queries III 需要你维护一种数据结构,支持两种操作: 单点修改 求一个区间的最大子段和 # 解题思路 一个区间的最大子段 ...

  6. Can you answer these queries III(线段树)

    Can you answer these queries III(luogu) Description 维护一个长度为n的序列A,进行q次询问或操作 0 x y:把Ax改为y 1 x y:询问区间[l ...

  7. SPOJ GSS3 Can you answer these queries III

    Time Limit: 330MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Description You are g ...

  8. spoj 1557 GSS3 - Can you answer these queries III 线段树

    题目链接 给出n个数, 2种操作, 一种是将第x个数改为y, 第二种是询问区间[x,y]内的最大连续子区间. 开4个数组, 一个是区间和, 一个是区间最大值, 一个是后缀的最大值, 一个是前缀的最大值 ...

  9. SP1716 GSS3 - Can you answer these queries III

    题面 题解 相信大家写过的传统做法像这样:(这段代码蒯自Karry5307的题解) struct SegmentTree{ ll l,r,prefix,suffix,sum,maxn; }; //.. ...

随机推荐

  1. 在学习ROS过程中碰到的一些问题--1

    好了,这是接触ROS的第三周了,初步了解了一下ROS,很多问题自己还是无法解决,但是想着很久没有在blog上记录自己的学习过程,就先胡乱写一下吧.^-^ 1.关于ROS各种基本概念的理解 这方面知识建 ...

  2. [bzoj 4887] [Tjoi2017]可乐

    传送门 Description 加里敦星球的人们特别喜欢喝可乐.因而,他们的敌对星球研发出了一个可乐机器人,并且 放在了加里敦星球的1号城市上.这个可乐机器人有三种行为:停在原地,去下一个相邻的 城市 ...

  3. docker搭建hadoop HA出错问题总结记录。

    错误1: ssh连接云主机: ssh root@39.106.xx.xx 报错:THE AUTHENTICITY OF HOST XX CAN’T BE ESTABLISHED 解决办法: ssh - ...

  4. ngx.shared.DICT.get 详解

    ngx.shared.DICT.get 原文: ngx.shared.DICT.get syntax: value, flags = ngx.shared.DICT:get(key) context: ...

  5. JavaScript WebSocket 使用总结

    翻看之前写的 Highcharts使用总结  和 前后台交互之传参方式,想对 WebSocket 单独写一个使用总结. 一.认识 WebSocket . WebSocket 是 H5 新出的一种协议, ...

  6. python 中的 [-1::1] 啥意思

    取倒数第一个

  7. SpringBoot之返回json数据

    一.创建一个springBoot个项目 二.编写实体类 /** * 返回Json数据实体类 */ public class User { private int id; private String ...

  8. Facebook libra开发者文档- 3 -Life of a Transaction交易生命周期

    Life of a Transaction交易的生命周期 https://developers.libra.org/docs/life-of-a-transaction 为了更深入地了解Libra交易 ...

  9. python读取csv文件、excel文件并封装成dict类型的list,直接看代码

    # coding=UTF-8import csvimport xlrd class ReaderFile(): """ 读取csv文件 filePath:文件路径 &qu ...

  10. SM30维护视图屏蔽按钮与增加选择条件

    *---------------------------------------------------------------------- * TABLES/Structure *-------- ...