0.题目大意

给出一个序列,每次查询一个区间的最大子段和的端点和值。序列长度 \(n \le 10^{5}\) 。

1.思路

显然应该使用线段树。题目要求每次求一个区间的最大子段和,那么在线段树节点中应该维护这个节点的最大子段和。然而,只维护最大子段和是无法从子节点合并出父节点的。

考虑一个节点,它的最大子段和可能有以下几个来源:

|_____________________________|               <-节点
|_________| <-最大子段和
|_______________ |_____________| <-左右子节点
|_____________________________|               <-节点
|_________| <-最大子段和
|_______________ |_____________| <-左右子节点
|_____________________________|               <-节点
|_________________| <-最大子段和
|_______________ |_____________| <-左右子节点

情况1、2比较容易处理(直接照搬子节点的最大子段和),下面主要考虑情况3(最大子段和跨过中点)。

注意到可以把情况3拆分成这样:

|_____________________________|               <-节点
|__________| |_____| <-最大子段和
|______________| |_____________| <-左右子节点

即拆分成左子节点的后缀和右子节点的前缀,所以考虑维护每个节点的 最大前缀和最大后缀和 ,情况3就可以表示为左子节点的最大后缀和和右子节点的最大前缀和的并,然后就可以愉快地合并了。

解决了如何合并的问题,剩下的几乎就是模板了

2.坑点与吐槽

  1. 题目要求按照字典序输出,这莫名其妙地增加了许多难度
  2. 需要输出端点,这莫名其妙地增加了许多要维护的变量,又莫名其妙地增加了许多难度
  3. 综上所述,出题人是一个大毒瘤,建议枪毙

3.Code

#include <bits/stdc++.h>
using namespace std;
#define MAXN 100000
#define INF 0x3fffffff
struct answ{
int i,j,k;
answ(){i=j=k=0;}
answ(int _i,int _j,int _k){i=_i;j=_j;k=_k;}
};
struct segment_tree{
int lp,rp;
segment_tree *ls,*rs;
int sum,max_qz_sum,max_qz_sum_rp,max_hz_sum,max_hz_sum_lp,max_sum,max_sum_lp,max_sum_rp;
segment_tree(int a[],int l,int r){
lp=l;
rp=r;
if(l==r){
ls=rs=NULL;
sum=max_qz_sum=max_hz_sum=max_sum=a[l];
max_qz_sum_rp=max_hz_sum_lp=max_sum_lp=max_sum_rp=l;
}else{
int mid=(l+r)/2;
ls=new segment_tree(a,l,mid);
rs=new segment_tree(a,mid+1,r);
sum=ls->sum+rs->sum;
if(ls->max_qz_sum >= ls->sum+rs->max_qz_sum){//情况1
max_qz_sum=ls->max_qz_sum;
max_qz_sum_rp=ls->max_qz_sum_rp;
}else{
max_qz_sum=ls->sum+rs->max_qz_sum;
max_qz_sum_rp=rs->max_qz_sum_rp;
}
if(rs->max_hz_sum >= rs->sum+ls->max_hz_sum){//情况2
max_hz_sum=rs->max_hz_sum;
max_hz_sum_lp=rs->max_hz_sum_lp;
}else{
max_hz_sum=rs->sum+ls->max_hz_sum;
max_hz_sum_lp=ls->max_hz_sum_lp;
}
if(ls->max_sum >= rs->max_sum){//情况3
max_sum=ls->max_sum;
max_sum_lp=ls->max_sum_lp;
max_sum_rp=ls->max_sum_rp;
}else{
max_sum=rs->max_sum;
max_sum_lp=rs->max_sum_lp;
max_sum_rp=rs->max_sum_rp;
}
if(max_sum<ls->max_hz_sum+rs->max_qz_sum){
max_sum=ls->max_hz_sum+rs->max_qz_sum;
max_sum_lp=ls->max_hz_sum_lp;
max_sum_rp=rs->max_qz_sum_rp;
}else if(max_sum==ls->max_hz_sum+rs->max_qz_sum){
if(max_sum_lp>ls->max_hz_sum_lp){
max_sum=ls->max_hz_sum+rs->max_qz_sum;
max_sum_lp=ls->max_hz_sum_lp;
max_sum_rp=rs->max_qz_sum_rp;
}else if(max_sum_lp==ls->max_hz_sum_lp){
if(max_sum_rp>rs->max_qz_sum_rp){
max_sum=ls->max_hz_sum+rs->max_qz_sum;
max_sum_lp=ls->max_hz_sum_lp;
max_sum_rp=rs->max_qz_sum_rp;
}
}
}//如您所见,由于愚蠢的“按字典序输出”存在,代码莫名其妙地增加了许多
}
}
answ query_qz(int r){//查询最大前缀和
if(r>=rp){
return answ(0,max_qz_sum_rp,max_qz_sum);
}else{
answ res=ls->query_qz(r);
if(r>=rs->lp){
answ R=rs->query_qz(r);
if(res.k<R.k+ls->sum){
res=answ(0,R.j,R.k+ls->sum);
}
}
return res;
}
}
answ query_hz(int l){//查询最大后缀和
if(l<=lp){
return answ(max_hz_sum_lp,0,max_hz_sum);
}else{
answ res=rs->query_hz(l);
if(l<=ls->rp){
answ L=ls->query_hz(l);
if(res.k<L.k+rs->sum){
res=answ(L.i,0,L.k+rs->sum);
}
}
return res;
}
}
answ query(int l,int r){//查询最大字段和
if(l<=lp&&rp<=r){
return answ(max_sum_lp,max_sum_rp,max_sum);
}else{
answ res(0,0,-INF),L,R;
if(l<=ls->rp){
L=ls->query(l,r);
if(L.k>res.k){
res=L;
}
}
if(r>=rs->lp){
R=rs->query(l,r);
if(R.k>res.k){
res=R;
}
}
if(l<=ls->rp&&r>=rs->lp){
L=ls->query_hz(l);
R=rs->query_qz(r);
if(L.k+R.k>res.k){
res=answ(L.i,R.j,L.k+R.k);
}
}
return res;
}
}
};
int n,m,a[MAXN+5],sum[MAXN+5];
int main(){
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
sum[i]=sum[i-1]+a[i];
}
segment_tree data(a,1,n);
for(int i=1;i<=m;i++){
int l,r;
cin>>l>>r;
if(r-l+1>33){//在数据量较小时使用暴力可以提高效率
answ ans=data.query(l,r);
cout<<ans.i<<" "<<ans.j<<" "<<ans.k<<endl;
}else{
int ansl=0,ansr=0,ans=-INF;
for(int j=l;j<=r;j++){
for(int k=j;k<=r;k++){
if(ans<sum[k]-sum[j-1]){
ansl=j;
ansr=k;
ans=sum[k]-sum[j-1];
}
}
}
cout<<ansl<<" "<<ansr<<" "<<ans<<endl;
}
}
return 0;
}
4.点一个赞罢QwQ

[HZOI] 山海经 题解的更多相关文章

  1. COGS 2416.[HZOI 2016]公路修建 & COGS 2419.[HZOI 2016]公路修建2 题解

    大意: [HZOI 2016]公路修建 给定一个有n个点和m-1组边的无向连通图,其中每组边都包含一条一级边和一条二级边(连接的顶点相同),同一组边中的一级边权值一定大于等于二级边,另外给出一个数k( ...

  2. COGS 2188. [HZOI 2015] Math 题解

      题目描述: 给定n个数X1-Xn,求下面式子的值(整数部分): n<=107,xi<=109且互不相同. 分析: 其实一开始看见这道题我也吓傻了,k这么大,再说我又是数论鶸渣,打死也不 ...

  3. cogs 2320. [HZOI 2015]聪聪的世界题解

    2320. [HZOI 2015]聪聪的世界 时间限制:6 s   内存限制:512 MB [题目描述] 背景: 聪聪的性取向有问题. 题目描述: 聪聪遇到了一个难题: 给出一个序列a1…an,完成以 ...

  4. COGS 2421.[HZOI 2016]简单的Treap 题解

    题目大意: 给定n个数及其优先级,求对应的符合最小堆性质的Treap的先序遍历. n<=500000. 解法: 目前为止我只想到了三种解法,其中第三种是正解. 1.暴力1 以优先级为关键字排序, ...

  5. COGS 2387.[HZOI 2016]2387题解

    题目大意: 给定一个有n个元素的数组,有m个操作,分为两种,分别是询问第k个x的下标和把下标为x的数修改为k. 题目设置了强制在线,故无法预先得知所有操作数. 思路: 有三种思路. 第一种:平衡树 b ...

  6. 【COGS】2287:[HZOI 2015]疯狂的机器人 FFT+卡特兰数+排列组合

    [题意][COGS 2287][HZOI 2015]疯狂的机器人 [算法]FFT+卡特兰数+排列组合 [题解]先考虑一维的情况,支持+1和-1,前缀和不能为负数,就是卡特兰数的形式. 设C(n)表示第 ...

  7. [cogs2314][HZOI 2015] Persistable Editor - 可持久化平衡树

    [cogs2314][HZOI 2015]Persistable Editor - 可持久化平衡树 题目链接 首先吐槽扯淡几句 [题目描述] 维护一种可持久化的文本编辑器,支持下列操作: 1 p st ...

  8. [HZOI 2016]我们爱数数

    [HZOI 2016]我们爱数数 题目大意: 一张圆桌,每个位置按顺时针从\(1\)到\(n\)编号.有\(n\)个人,编号从\(1\)到\(n\).如果编号为\(i\)的人坐到了编号为\(i\)的位 ...

  9. CSP-S 模拟测试57题解

    人生第一次A,B层一块考rank2,虽然说分差没几分,但还是值得纪念. 题解: T1 天空龙: 大神题,因为我从不写快读也没有写考场注释的习惯,所以不会做,全hzoi就kx会做,kx真大神级人物. T ...

随机推荐

  1. 【LeetCode】144. Binary Tree Preorder Traversal 解题报告(Python&C++&Java)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 迭代 日期 题目地址:https://leetc ...

  2. 【LeetCode】46. Permutations 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 解题方法 方法一:库函数 方法二:递归 方法三:回溯法 日期 题目地址:h ...

  3. 【剑指Offer】数字在排序数组中出现的次数 解题报告(Python)

    [剑指Offer]数字在排序数组中出现的次数 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interv ...

  4. Discrete Logging(poj2417)

    Discrete Logging Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5120   Accepted: 2319 ...

  5. CS5211替代CH7511B|设计DP转LVDS转接板|替代CH7511B

    CH7511B是一款DP转lvds屏转换芯片CH7511B是一款eDP转LVDS转换芯片.CH7511B将嵌入式DisplayPort信号转换为LVDS(低压差分信号).通过CH7511B的高级解码/ ...

  6. 中文字体css编码转换

    各大网站的字体选择 网站 字体 腾讯 font: 12px "宋体","Arial Narrow",HELVETICA; 淘宝 font: 12px/1.5 t ...

  7. NoSQL是什么(一)

    最常见的数据库可以分为下面的两种类型: RDBMS(关系型数据库):常见的关系型数据库有 Oracle.DB2.Microsoft SQL Server.Microsoft Access.MySQL: ...

  8. solr - 安装ik中文分词 和初始化富文本检索

    1.下载安装包 https://repo1.maven.org/maven2/org/apache/solr/solr-dataimporthandler/7.4.0/solr-dataimporth ...

  9. 详谈 Java工厂 ---工厂方法模式

    1.前言 有个场景,消费者需要付钱,有可能是使用支付宝.微信.银行卡,那么该怎么选择呢? 是不是想到了使用用if else判断?还是使用switch? 一个地方这样写还好,如果有很多这样的业务,难道都 ...

  10. 细谈 == 和 equals 的具体区别 【包括equals源码分析】

    1.前言 昨天舍友去面试,被面试官的问题难住了:俩个学生类除了学生姓名不同用.equal来比较. 我是一脸懵逼的 ,问题说的很模糊 , 理解字面意思为 :一个 实体类名叫Student ,内部属性有学 ...