Sample Input

3 1

1 2 3

1 1

Sample Output

Case 1:

1 1

线段树

L,R表示该区间的左右端点,sum表示该区间值的总和

l,r表示该区间连续的最大和的左右端点,maxall表示该区间的连续最大和

maxqj表示该区间的前缀连续最大和(即val[L]必取),qj表示该区间的前缀连续最大和右端点

maxhj表示该区间的后缀连续最大和(即val[R]必取),hj表示该区间的前缀连续最大和左端点

更新maxall:分3类讨论

1.连续最大和在左子树   或   几种情况中连续最大和相等且这种情况的连续最大和的左端点较小或相等

取左子树的连续最大和及端点

2.连续最大和在左右两子树   或   几种情况中连续最大和相等且这种情况的连续最大和的左端点较小

取左子树的后缀连续最大和加右子树的前缀连续最大和

3.连续最大和在右子树

取有子树的连续最大和及端点

更新maxqj:分两类讨论

1.前缀连续最大和在左右两子树

取左子树的区间值的总和加右子树的前缀连续最大和及端点

2.前缀连续最大和在左子树    或     几种情况中前缀连续最大和相等

取左子树的前缀连续最大和及端点

更新maxhj:分两类讨论

1.后缀连续最大和在左右两子树    或     几种情况中后缀连续最大和相等

 取右子树的区间值的总和加左子树的后缀连续最大和及端点

2.后缀连续最大和在右子树

取右子树的后缀连续最大和及端点

更新sum:把左右两子树的sum加起来

对于[a,b],我们用分治的思想,分三种情况讨论:

1.[a,b]在左子树,对左子树递归调用

2.[a,b]在右子树,对右子树递归调用

3.[a,b]在左右子树,对[a,mid],[mid+1,b]分别递归调用

t1(结构体)表示左子树返回的东西,t2表示右子树返回的东西,t表示该子树返回的东西

很明显,对于t的更新,和上面对tree的更新一模一样

如果当前区间与线段树中某区间重合,直接返回线段树中该区间存的内容即可

记得long long

#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
int val[],n,m;
struct xxx{
int L,R;
int l,r,qj,hj;
ll sum,maxqj,maxhj,maxall;
}tree[];
inline int read(){
int x;bool f;char c;
for (f=; (c=getchar())<''||c>''; f=c=='-');
for (x=c-''; (c=getchar())>=''&&c<=''; x=(x<<)+(x<<)+c-'');
return f?-x:x;
}
void pushup(int x)
{
ll x1=tree[x<<].maxall,x2=tree[x<<].maxhj+tree[x<<|].maxqj,x3=tree[x<<|].maxall;
if(x1>=x3&&(x1>x2||x1==x2&&tree[x<<].l<=tree[x<<].hj))
tree[x].maxall=x1,tree[x].l=tree[x<<].l,tree[x].r=tree[x<<].r;
else if(x2>=x3)
tree[x].maxall=x2,tree[x].l=tree[x<<].hj,tree[x].r=tree[x<<|].qj;
else
tree[x].maxall=x3,tree[x].l=tree[x<<|].l,tree[x].r=tree[x<<|].r;
if(tree[x<<].sum+tree[x<<|].maxqj>tree[x<<].maxqj)
tree[x].maxqj=tree[x<<].sum+tree[x<<|].maxqj,tree[x].qj=tree[x<<|].qj;
else
tree[x].maxqj=tree[x<<].maxqj,tree[x].qj=tree[x<<].qj;
if(tree[x<<|].sum+tree[x<<].maxhj>=tree[x<<|].maxhj)
tree[x].maxhj=tree[x<<|].sum+tree[x<<].maxhj,tree[x].hj=tree[x<<].hj;
else
tree[x].maxhj=tree[x<<|].maxhj,tree[x].hj=tree[x<<|].hj;
tree[x].sum=tree[x<<].sum+tree[x<<|].sum;
}
void build(int x,int l,int r)
{
if(l==r)
{
tree[x].sum=tree[x].maxqj=tree[x].maxhj=tree[x].maxall=(ll)val[l];
tree[x].l=tree[x].r=tree[x].qj=tree[x].hj=tree[x].L=tree[x].R=l;return;
}
tree[x].L=l;tree[x].R=r;
int mid=(l+r)>>;
build(x<<,l,mid);build(x<<|,mid+,r);pushup(x);
//cout<<l<<" "<<r<<" "<<tree[x].maxall<<" "<<tree[x].l<<" "<<tree[x].r<<tree[x].hj<<endl;
}
xxx query(int x,int l,int r)
{
if(l==tree[x].L&&r==tree[x].R)return tree[x];
int mid=(tree[x].L+tree[x].R)/;
if(r<=mid)return query(x<<,l,r);
else if(l>mid)return query(x<<|,l,r);
else
{
xxx t1=query(x<<,l,mid),t2=query(x<<|,mid+,r),t;
ll x1=t1.maxall,x2=t1.maxhj+t2.maxqj,x3=t2.maxall;
if(x1>=x3&&(x1>x2||x1==x2&&t1.l<=t1.hj))
t.maxall=x1,t.l=t1.l,t.r=t1.r;
else if(x2>=x3)
t.maxall=x2,t.l=t1.hj,t.r=t2.qj;
else
t.maxall=x3,t.l=t2.l,t.r=t2.r;
if(t1.sum+t2.maxqj>t1.maxqj)
t.maxqj=t1.sum+t2.maxqj,t.qj=t2.qj;
else
t.maxqj=t1.maxqj,t.qj=t1.qj;
if(t2.sum+t1.maxhj>=t2.maxhj)
t.maxhj=t2.sum+t1.maxhj,t.hj=t1.hj;
else
t.maxhj=t2.maxhj,t.hj=t2.hj;
return t;
} }
int main()
{
int T=;
while(~scanf("%d%d",&n,&m))
{
T++;
for(int i=;i<=n;i++)val[i]=read();
build(,,n);
printf("Case %d:\n",T);
for(int i=;i<=m;i++)
{
int a=read(),b=read();
xxx x=query(,a,b);
printf("%d %d\n",x.l,x.r);
}
}
return ;
}

[LA_3938]最大连续动态和的更多相关文章

  1. 把连续动态bmp转换为avi

    把动态bmp24转换为avi BYTE tmp_buf[1024*768*4]; //生成avi void BMPtoAVI(CString szAVIName, CString strBmpDir) ...

  2. 腾讯技术分享:GIF动图技术详解及手机QQ动态表情压缩技术实践

    本文来自腾讯前端开发工程师“ wendygogogo”的技术分享,作者自评:“在Web前端摸爬滚打的码农一枚,对技术充满热情的菜鸟,致力为手Q的建设添砖加瓦.” 1.GIF格式的历史 GIF ( Gr ...

  3. Unity 重要基础知识点

    这是两个月前的学习记录,发出来了下,如果有误欢迎大家指出: 脚本生命周期 //每当脚本被加载时调用一次 // 1.   在Awake中做一些初始化操作 void Awake(){ //初始化publi ...

  4. 堆栈指针 ---delete 使用

    对拥有堆中一个有效对象的地址的指针进行删除操作的结果,是将这个堆内存的状态从“使用中” 变为“可用”(此时的可用就是指可以调用内存)释放了,可以再次覆盖此处;;     对指针内存进行删除操作后,指针 ...

  5. I帧 B帧 p帧 IDR帧的区别

    转自:http://blog.csdn.net/sphone89/article/details/8086071 IDR(Instantaneous Decoding Refresh)--即时解码刷新 ...

  6. 论Collision Detection的作用

    今天有空就仔细研究了一下Collision Detection的问题,以前总是弄不明白Continuous和Continuous Dynamic到底有什么区别,今天算是彻底弄明白了,官方文档说的太晦涩 ...

  7. [原]Unity3D深入浅出 - 物理引擎之刚体部件(Rigidbody)

    在虚拟世界中,任何物体都是没有活力的,要想变的真实,Rigidbody是必不可少的组件,下面介绍Rigidbody的各个属性: Mass:质量 Drag:阻力,对象在运动时遇到的空气阻力,0表示没有空 ...

  8. iOS-直播开发(开发从底层做起)

    一直在忙, 也没写过几次播客! 但一直热衷于直播开发技术, 公司又不是直播方向的, 所以就年前忙里偷袭研究了一下直播开发, 然后翻阅了很多大神的技术博客等, 写了一个简单的Demo, 又根据网上大神们 ...

  9. 浓缩的才是精华:浅析GIF格式图片的存储和压缩

    成文迪, 在Web前端摸爬滚打的码农一枚,对技术充满热情的菜鸟,致力为手Q的建设添砖加瓦. GIF格式的历史 GIF(Graphics Interchange Format)原义是"图像互换 ...

随机推荐

  1. SPOJ1026 概率DP

    Favorite Dice BuggyD loves to carry his favorite die around. Perhaps you wonder why it's his favorit ...

  2. 16.2,docker网络

      Docker 允许通过外部访问容器或容器互联的方式来提供网络服务. 端口映射允许外部访问容器 --link 容器互联 容器桥接网络 .通过--link容器通信,给test2添加一个hosts解析记 ...

  3. C17K:Lying Island

    链接 题意: 有n个人,每个人可能会说: 第x个人是好人/坏人 如果第x个人是好人/坏人,则第y个人是好人/坏人 思路: 状压dp,首先每个人所说的人只能是他前面10个人,所以对于第i个人记录下,他前 ...

  4. CodeForces 873F Forbidden Indices 后缀数组

    忘了当时怎么做的了,先把代码贴上,保存一下后缀数组模板. #include <cstdio> #include <cstring> #include <algorithm ...

  5. ARabevaluator 颜色渐变控制类

    参考资料: http://blog.csdn.net/qq_33456552/article/details/52092865 实现渐变效果: ArgbEvaluator argbEvaluator; ...

  6. app图标

    1.http://www.iconfont.cn/ 在里面可以搜索你想要的图标: 比如关闭. 2.选择一个好看的下载png 3.打开ps,ctrl n新建一个图层. 把你下载的png弄到上面,然后关闭 ...

  7. 用CSS伪元素制作箭头

    现在让我们开始制作箭头吧! 在开始前,你要知道如何用CSS去画一个三角形,如果还不清楚可以看看这里纯CSS画各种图形 我们用到两个CSS伪元素,before和after,它们属于行内元素,但可以用di ...

  8. 《Cracking the Coding Interview》——第4章:树和图——题目5

    2014-03-19 04:11 题目:设计算法检查一棵二叉树是否为二叉搜索树. 解法:既然是二叉搜索树,也就是说左子树所有节点都小于根,右子树所有节点都大于根.如果你真的全都检查的话,那就做了很多重 ...

  9. 运用Pascal来破坏DLL的一个实例

    运用Pascal来破坏DLL文件的一个实例 关于Pascal静态调用和动态的调用DLL的学习您可以看Delphi/Lazarus栏目. Uses Dos; {调用DOS库} Const Root='C ...

  10. Python学习-day20 django进阶篇

    Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去调用数据访问层执行 ...