[冬令营Day1 T2]sequence
2024-09-06 22:35:07
题目描述 Description
|
||||||||
给一个长度为N的序列以及Q的询问,每次两个参数l,r,问你序列[l,r]中的最大连续和
|
||||||||
输入描述 Input Description
|
||||||||
一行二个正整数N,Q。 |
||||||||
输出描述 Output Description
|
||||||||
对于每个询问,输出一行一个整数,描述答案。
|
||||||||
样例输入 Sample Input
|
||||||||
4 3
1 -2 3 2 1 4 1 2 2 2 |
||||||||
样例输出 Sample Output
|
||||||||
5
1
0
|
||||||||
数据范围及提示 Data Size & Hint
|
||||||||
|
线段树。对于每个节点,维护三个值。sum,suml,sumr表示该点的最大连续和,最大前缀和和最大后缀和。
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long LL;
inline int read()
{
int x=,f=;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-;c=getchar();}
while(isdigit(c)){x=x*+c-'';c=getchar();}
return x*f;
}
const int oo=;
const int maxn=;
int n,q,a[maxn],x,y;
LL pre[maxn],sum[maxn],suml[maxn],sumr[maxn];
void build(int l,int r,int o)
{
if(l==r)
{
suml[o]=sumr[o]=sum[o]=pre[r]-pre[l-];
return;
}
int mid=(l+r)>>,lo=o<<,ro=lo+;
build(l,mid,lo);
build(mid+,r,ro);
sum[o]=max(sum[lo],sum[ro]);
sum[o]=max(sum[o],sumr[lo]+suml[ro]);
suml[o]=max(suml[lo],pre[mid]-pre[l-]+suml[ro]);
sumr[o]=max(sumr[ro],pre[r]-pre[mid]+sumr[lo]);
return;
}
LL queryl(int x,int y,int l,int r,int o)
{
if(x==l && y==r) return sumr[o];
int mid=(l+r)>>,lo=o<<,ro=lo+;
if(x>mid) return queryl(x,y,mid+,r,ro);
else
{
LL tmp=pre[r]-pre[mid]+queryl(x,mid,l,mid,lo);
return max(sumr[ro],tmp);
}
}
LL queryr(int x,int y,int l,int r,int o)
{
if(x==l && y==r) return suml[o];
int mid=(l+r)>>,lo=o<<,ro=lo+;
if(y<=mid) return queryr(x,y,l,mid,lo);
else
{
LL tmp=pre[mid]-pre[l-]+queryr(mid+,y,mid+,r,ro);
return max(suml[lo],tmp);
}
}
LL query(int x,int y,int l,int r,int o)
{
if(x<=l && y>=r)return sum[o];
int mid=(l+r)>>,lo=o<<,ro=lo+;
if(y<=mid) return query(x,y,l,mid,lo);
else if(x>mid) return query(x,y,mid+,r,ro);
else
{
LL ls,rs;
ls=queryl(x,mid,l,mid,lo);
rs=queryr(mid+,y,mid+,r,ro);
return max(max(query(x,mid,l,mid,lo),query(mid+,y,mid+,r,ro)),rs+ls);
}
}
int main()
{
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
n=read();q=read();
for(int i=;i<=n;i++)a[i]=read(),pre[i]=pre[i-]+a[i];
build(,n,);
while(q--)
{
x=read();y=read();
LL tmp=query(x,y,,n,);
if(tmp<)tmp=;
printf("%lld\n",tmp);
}
return ;
}
对于后三个点肯定没戏,毕竟线段树常数那么大。满分做法好像是整体二分,然而并不会,等着以后来填坑吧。
最新文章
- 对抗假人 —— 前后端结合的 WAF
- sql 获取一批指定范围且不重复的随机数
- 学习django之正则表达式re模块
- Reverse a singly linked list
- 用thinkphp写的一个例子:抓取网站的内容并且保存到本地
- 改变DEV控件的字体 z
- java技术学习网址收藏
- VS2015操作Oracle数据需要做那些设置?
- java8中Stream数据流
- Android之Material Dialogs详解
- 安卓获取签名SHA1
- monkeyrunner环境配置
- 常用java的正则表达式
- display:table-cell几种应用
- vmware 下找不到ifcfg-eth0的问题
- ie edge 自动给数字加下划线
- Android-PullToRefresh 下拉刷新增加setOnItemLongClickListener
- Django 2.0.1 官方文档翻译: 编写你的第一个 Django app,第一部分(Page 6)
- nginx File not found 错误(转)
- [转]tppabs是什么?如何去除tppabs?
热门文章
- STM32调试,发现HAL_Init();之后无法调试,甚至无法让程序停下来
- 去掉DataGridView最后一行的空白行,删除空白行
- snowflake ID生成器
- [转帖]【译】RAID的概念和RAID对于SQL性能的影响
- 运维开发实践——基于Sentry搭建错误日志监控系统
- RabbitMQ 在Windows环境下安装
- nginx报错111: Connection refused
- TransactionScope 使用的注意事项
- MarkDown 常用语法规则
- 用友U9 基础使用文件所在目录