Can you answer these queries III
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的更多相关文章
- 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 ...
- GSS3 SPOJ 1716. Can you answer these queries III gss1的变形
gss2调了一下午,至今还在wa... 我的做法是:对于询问按右区间排序,利用splay记录最右的位置.对于重复出现的,在splay中删掉之前出现的位置所在的节点,然后在splay中插入新的节点.对于 ...
- 数据结构(线段树):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] ...
- 「 SPOJ GSS3 」 Can you answer these queries III
# 题目大意 GSS3 - Can you answer these queries III 需要你维护一种数据结构,支持两种操作: 单点修改 求一个区间的最大子段和 # 解题思路 一个区间的最大子段 ...
- 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 ...
- 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; }; //.. ...
随机推荐
- 全国行政区域代码(免费来拿) xls格式 可直接导入
全部区域代码 地址:https://pan.baidu.com/s/1Elz-zW_nLS8YR8GZAn3WRw 提取码:ze3s
- springboot连接redis进行CRUD
springboot连接redis进行CRUD: 1.添加以下依赖: <dependency> <groupId>org.springframework.boot</gr ...
- PL/SQL配置和连接远端数据库
1. 安装与配置 (1) 安装 因为是免安装的绿色版,所以解压到目录就可以了,保证目录中没有空格.下划线和中文字符. 还有一点,PL/SQL需要和Oracle的版本一致,都是32位或者都是64位,否则 ...
- SQL语言Select经典语句
-- 示例数据 Select * From Employee Select * From Department -- 返回工资最高的员工的信息 Select * From Employee where ...
- Row_Number() and Rank() in SQL
1. 数据表实例数据 2. 使用Row_Number()方法给每一行数据添加一个唯一编号, 可以按照某一列进行排序. 3. 使用Partition by Column在一个Partition内进行编号 ...
- 002-创建型-03-单例模式(Singleton)【7种】、spring单例及原理
一.概述 保证一个类仅有一个实例,并提供一个全局访问点 私有构造器.线程安全.延迟加载.序列化和反序列化安全.反射攻击 1.1.适用场景 1.在多个线程之间,比如servlet环境,共享同一个资源或者 ...
- 阶段5 3.微服务项目【学成在线】_day18 用户授权_12-前端集成认证授权-携带JWT授权
携带JWT授权 登陆后jwt已经存到了sessionStorage里面 当进行微服务的请求就要携带令牌.我们在拦截器里面做文章. 在axios的intercepters拦截器上 手工的给这个课程 造一 ...
- NodeJs本地搭建服务器,模拟接口请求,获取json数据
最近在学习Node.js,虽然就感觉学了点皮毛,感觉这个语言还不错,并且也会一步步慢慢的学着的,这里实现下NodeJs本地搭建服务器,模拟接口请求,获取json数据. 具体的使用我就不写了,这个博客写 ...
- 给 textbox TextMode="password" 赋值后显示出来
在做一个修改用户资料的页面的时候,发现用 <asp:TextBox ID="txtPwd" runat="server" TextMode="P ...
- linux下无法启动webdriver问题
linux下无法启动webdriver问题: 查看是否有足够多的webdriver进程: ps -ef | grep chromedriver kill -9 `ps -ef |grepchromed ...