题目描述 Description
给一个长度为N的序列以及Q的询问,每次两个参数l,r,问你序列[l,r]中的最大连续和
输入描述 Input Description

一行二个正整数N,Q。
  接下来一行N个整数,描述序列A。
  接下来Q行,每行两个参数L,R,描述一个询问。

输出描述 Output Description
对于每个询问,输出一行一个整数,描述答案。
样例输入 Sample Input
4 3
1 -2 3 2
1 4
1 2
2 2
样例输出 Sample Output
5
1
0
数据范围及提示 Data Size & Hint
测试点编号 数据范围及特殊说明
1,2,3 N,Q≤1000
4,5,6,7 N,Q≤10^5
8,9,10 N≤10^5,Q≤10^6

线段树。对于每个节点,维护三个值。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 ;
}

对于后三个点肯定没戏,毕竟线段树常数那么大。满分做法好像是整体二分,然而并不会,等着以后来填坑吧。

最新文章

  1. 对抗假人 —— 前后端结合的 WAF
  2. sql 获取一批指定范围且不重复的随机数
  3. 学习django之正则表达式re模块
  4. Reverse a singly linked list
  5. 用thinkphp写的一个例子:抓取网站的内容并且保存到本地
  6. 改变DEV控件的字体 z
  7. java技术学习网址收藏
  8. VS2015操作Oracle数据需要做那些设置?
  9. java8中Stream数据流
  10. Android之Material Dialogs详解
  11. 安卓获取签名SHA1
  12. monkeyrunner环境配置
  13. 常用java的正则表达式
  14. display:table-cell几种应用
  15. vmware 下找不到ifcfg-eth0的问题
  16. ie edge 自动给数字加下划线
  17. Android-PullToRefresh 下拉刷新增加setOnItemLongClickListener
  18. Django 2.0.1 官方文档翻译: 编写你的第一个 Django app,第一部分(Page 6)
  19. nginx File not found 错误(转)
  20. [转]tppabs是什么?如何去除tppabs?

热门文章

  1. STM32调试,发现HAL_Init();之后无法调试,甚至无法让程序停下来
  2. 去掉DataGridView最后一行的空白行,删除空白行
  3. snowflake ID生成器
  4. [转帖]【译】RAID的概念和RAID对于SQL性能的影响
  5. 运维开发实践——基于Sentry搭建错误日志监控系统
  6. RabbitMQ 在Windows环境下安装
  7. nginx报错111: Connection refused
  8. TransactionScope 使用的注意事项
  9. MarkDown 常用语法规则
  10. 用友U9 基础使用文件所在目录