[codevs3981]动态最大子段和不带修改(线段树)
2024-10-18 18:13:40
解题关键:最大子段和需要多个信息维护。
注意查询时的pushup。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<iostream>
#define inf (1<<62)
using namespace std;
typedef long long ll;
const int maxn=;
ll a[maxn],sum[maxn<<],la[maxn<<],ra[maxn<<],gss[maxn<<];
int n;
struct node{
ll sum,la,ra,gss;
}; void pushup(int rt){
int l=rt<<,r=rt<<|;
la[rt]=max(la[l],sum[l]+la[r]);
ra[rt]=max(ra[r],sum[r]+ra[l]);
gss[rt]=max(ra[l]+la[r],gss[l]);
gss[rt]=max(gss[rt],gss[r]);
sum[rt]=sum[l]+sum[r];
}
void build(int rt,int l,int r){
if(l==r){
la[rt]=ra[rt]=gss[rt]=sum[rt]=a[l];
return;
}
int mid=(l+r)>>;
build(rt<<,l,mid);
build(rt<<|,mid+,r);
pushup(rt);
} //query有问题,也需要pushup
node query(int rt,int l,int r,int tl,int tr){
if(tl<=l&&tr>=r){
return {sum[rt],la[rt],ra[rt],gss[rt]};
}
int mid=(l+r)>>;
if(tr<=mid) return query(rt<<, l, mid,tl, tr);
if(tl>mid) return query(rt<<|, mid+, r,tl, tr);
node lo=query(rt<<, l, mid,tl, tr),ro=query(rt<<|, mid+, r,tl, tr),ans;
ans.sum = lo.sum + ro.sum;
ans.gss = max(max(lo.gss, ro.gss), lo.ra + ro.la);
ans.la = max(lo.la, lo.sum + ro.la);
ans.ra = max(ro.ra, ro.sum + lo.ra);
return ans;
} int main(){
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%lld",a+i);
build(,,n);
int q,t1,t2;
scanf("%d",&q);
for(int i=;i<=q;i++){
scanf("%d%d",&t1,&t2);
ll ans=query(,,n,t1,t2).gss;
printf("%lld\n",ans);
}
return ;
}
最新文章
- Oracle Entity6 在查询View的时候出现重复数据
- curl --connect-timeout 判断国内外网络windows 批处理
- 史航416第八次作业&;总结
- ASP.NET 页生命周期
- [转]RamDisk导致远程桌面客户端无法启动问题
- Scrum 项目——1
- Android学习笔记之蓝牙通信...
- 动态执行SQL语句
- explode and implode
- J2EE分布式事务中的提交、回滚方法调用异常。
- iOS应用的crash日志的分析基础
- python 使用模块
- 新建Android项目的时候,选择SDK的区别
- OAuth流程
- hadoop中联结不同来源数据
- Linux操作系统-安装JAVA
- python全栈开发-Day7 字符编码总结
- SVG矢量图学习实例
- Kernel Functions-Introduction to SVM Kernel &; Examples - DataFlair
- 一款Timer倒计时器