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. java循环获取多天时间

    通过开始时间和结束时间循环获取时间: SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); Date star ...

  2. 【MongoDB】查询字段对应的数组中包含某个值

    在MongoDB操作的时候,我们可能会遇到查询[字段对应的数组中包含某个值]的数据,查询语句如下,假设表名为user. 示例1 数据 { id: 1, state_arr: [ "123&q ...

  3. HNOI2009有趣的数列

    首先next_permutation打表,发现Cat规律. 其实考试的时候这么做没什么问题,而且可以节省异常多的时间,那么现在我们来想一下why. 首先我拿模型法解释一下,我们把2n个数看成2n个人, ...

  4. PL/SQL配置和连接远端数据库

    1. 安装与配置 (1) 安装 因为是免安装的绿色版,所以解压到目录就可以了,保证目录中没有空格.下划线和中文字符. 还有一点,PL/SQL需要和Oracle的版本一致,都是32位或者都是64位,否则 ...

  5. 自定义控件之Region区域

    构造Region 直接构造 public Region(Region region) //复制一个同样的Region变量 public Region(Rect r) public Region(int ...

  6. Python中的logging模块就这么用

    Python中的logging模块就这么用 1.日志日志一共分成5个等级,从低到高分别是:DEBUG INFO WARNING ERROR CRITICALDEBUG:详细的信息,通常只出现在诊断问题 ...

  7. osg Shader 着色器

    #ifdef _WIN32 #include <Windows.h> #endif // _WIN32 #include <osg/Group> #include <os ...

  8. -bash: netstat: 未找到命令

    [root@localhost ~]# netstat -lunpt -bash: netstat: 未找到命令 [root@localhost ~]# yum -y install net-tool ...

  9. 阶段5 3.微服务项目【学成在线】_day17 用户认证 Zuul_18-身份校验-测试

    在顶级域名下配置 网关的地址在上面配置一下 重启nginx 拒绝访问后面的代码都加上 return null 开始测试 换成域名的方式访问 有cookie.但是拿不到header 加上header测试 ...

  10. Qt编写自定义控件48-面板窗体控件

    一.前言 很多时候需要有一个控件,能够替代容器控件,自动容纳多个widget,自适应宽高,然后提供滚动条功能,这就必然需要用到QScrollArea控件,可设置各个子面板的间距等,也在很多系统中用到, ...