当前位置: 首页 > news >正文

(线段树)SP2916 GSS5 / nfls #2899 查询最大子段和 题解

题意

在这里插入图片描述
(nflsoj 数据以及实际数据)n,m≤105n,m\le 10^5n,m105ai∈[−104,104]a_i\in[-10^4,10^4]ai[104,104]

思路

如果区间不交,即 r1<l2r_1<l_2r1<l2,那么就把前缀和扔上线段树,在左区间查最小值、右区间找最大值,相减即可。也可以维护一段区间的最大前缀和 lmalmalma、最大后缀和 rmarmarma,钦定 lma,rmalma,rmalma,rma 至少有一个元素。答案就是 lma[l1,r1]+sum(r1,l2)+rma[l2,r2]lma_{[l_1,r_1]}+sum_{(r_1,l_2)}+rma_{[l_2,r_2]}lma[l1,r1]+sum(r1,l2)+rma[l2,r2]

但是这里会出现区间有交的情况,本题的考点就是这里的分类讨论,一共有 444 种情况以及细节,对于答案区间 [x,y][x,y][x,y]

  • x,y∈[l2,r1]x,y\in[l_2,r_1]x,y[l2,r1]:答案为区间 [l2,r1][l_2,r_1][l2,r1] 的最大子段和,维护方法同 GSS1;
  • x∈[l1,l2],y∈[l2,r1]x\in[l_1,l_2],y\in[l_2,r_1]x[l1,l2],y[l2,r1]:答案为 rma[l1,l2]+lma[l2,r1]−al2rma_{[l_1,l_2]}+lma_{[l_2,r_1]}-a_{l_2}rma[l1,l2]+lma[l2,r1]al2
  • x∈[l2,r1],y∈[r1,r2]x\in[l_2,r_1],y\in[r_1,r_2]x[l2,r1],y[r1,r2]:答案为 rma[l2,r1]+lma[r1,r2]−ar1rma_{[l_2,r_1]}+lma_{[r_1,r_2]}-a_{r_1}rma[l2,r1]+lma[r1,r2]ar1
  • x∈[l1,l2],y∈[r1,r2]x\in[l_1,l_2],y\in[r_1,r_2]x[l1,l2],y[r1,r2]:答案为 rma[l1,l2]+sum(l2,r1)+lmar1,r2−[l2=r1]al2rma_{[l_1,l_2]}+sum_{(l_2,r_1)}+lma_{r_1,r_2}-[l_2=r_1]a_{l_2}rma[l1,l2]+sum(l2,r1)+lmar1,r2[l2=r1]al2

444 种情况要考虑 l2=r1l_2=r_1l2=r1 的情况。画个图会好理解。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ls u<<1
#define rs u<<1|1
const ll N=1e5+9,inf=3e14;
ll T,n,Q;
ll a[N];
struct SegT
{struct node{ll sum;ll lma,rma,ans;}T[N<<2];node add(node a,node b){node ret;ret.sum=a.sum+b.sum;ret.lma=max(a.lma,a.sum+b.lma);ret.rma=max(b.rma,b.sum+a.rma);ret.ans=max(max(a.ans,b.ans),a.rma+b.lma);return ret;}void pushup(ll u){T[u]=add(T[ls],T[rs]);}void build(ll u,ll l,ll r){T[u]=(node){-inf,-inf,-inf,-inf};if(l==r){T[u].sum=T[u].ans=T[u].lma=T[u].rma=a[l]; return;}ll mid=(l+r)>>1;build(ls,l,mid);build(rs,mid+1,r);pushup(u);}node get_info(ll u,ll l,ll r,ll ql,ll qr){if(qr<ql)return {0,0,0,0};if(ql<=l&r<=qr)return T[u];ll mid=(l+r)>>1;if(qr<=mid)return get_info(ls,l,mid,ql,qr);if(ql>mid)return get_info(rs,mid+1,r,ql,qr);return add(get_info(ls,l,mid,ql,qr),get_info(rs,mid+1,r,ql,qr));//返回结构体,条件反转,add函数在结构体之间运算 }
}A;
ll query(ll l1,ll r1,ll l2,ll r2)
{if(r1<l2)return A.get_info(1,1,n,l1,r1).rma+A.get_info(1,1,n,r1+1,l2-1).sum+A.get_info(1,1,n,l2,r2).lma;return max(max(A.get_info(1,1,n,l2,r1).ans,A.get_info(1,1,n,l1,l2).rma+A.get_info(1,1,n,l2+1,r1-1).sum+A.get_info(1,1,n,r1,r2).lma-(l2==r1?a[l2]:0)),max(A.get_info(1,1,n,l1,l2).rma+A.get_info(1,1,n,l2,r1).lma-a[l2],A.get_info(1,1,n,l2,r1).rma+A.get_info(1,1,n,r1,r2).lma-a[r1]));
}
int main()
{scanf("%lld",&T);while(T--){scanf("%lld",&n);for(int i=1;i<=n;i++)scanf("%lld",&a[i]);A.build(1,1,n);scanf("%lld",&Q);while(Q--){ll l1,r1,l2,r2;scanf("%lld%lld%lld%lld",&l1,&r1,&l2,&r2);printf("%lld\n",query(l1,r1,l2,r2));}}return 0;
}
http://www.dtcms.com/a/309171.html

相关文章:

  • STL进阶典题整理 2025.7.30-2025.8.1
  • 关于继承的一些知识(C++)
  • react-native在mac的m2芯片下,pod install安装glog的时候报错
  • bmcweb工作流程
  • 【科研绘图系列】R语言绘制环状分组显著性柱状堆积图
  • Spring AI 系列之三十 - Spring AI Alibaba-其它模型
  • CSS font-weight:500不生效
  • Git 命令使用指南:从入门到进阶
  • 动态规划(数位统计dp 状态压缩dp 树形dp 记忆化搜索) from y总
  • 【C语言】字符函数与字符串函数详解
  • http请求访问响应慢问题解决的基本思路
  • 基于python大数据的招聘数据可视化及推荐系统
  • natapp的报错Tunnel StatusReconnecting...
  • STM32芯片简述
  • 使用GPU和NPU视频生成的优劣对比
  • 人工智能与金融:金融服务的重塑
  • Linux9 root密码修改
  • armbian 启用nginx并设置访问密码
  • CTF实战:用Sqlmap破解表单输入型SQL注入题(输入账号密码/usernamepassword)
  • SpringBoot AI应用实战:从图像识别到预测分析
  • 【通用视觉框架】基于OpenCvSharp+WPF+YOLO开发的仿VisionMaster的通用视觉框架软件,全套源码,开箱即用
  • 机器人芯片:智能机器的“大脑”与未来趋势
  • Nature Machine Intelligence 面向机器人操作有效滑移控制的仿生轨迹模块
  • alaxea机器人由星海图人工智能科技有限公司研发的高性能仿人形机器人
  • 【LeetCode 热题 100】155. 最小栈
  • PL-0功能拓展及基于VSCode的IDE配置
  • kotlin语法和特性分析
  • PDFsam免费开源!PDF分割合并工具
  • 华为数通HCIP
  • 为什么我们需要提示词增强工程PEE(Prompt Enhancement Engineering )