[LA_3938]最大连续动态和
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]最大连续动态和的更多相关文章
- 把连续动态bmp转换为avi
把动态bmp24转换为avi BYTE tmp_buf[1024*768*4]; //生成avi void BMPtoAVI(CString szAVIName, CString strBmpDir) ...
- 腾讯技术分享:GIF动图技术详解及手机QQ动态表情压缩技术实践
本文来自腾讯前端开发工程师“ wendygogogo”的技术分享,作者自评:“在Web前端摸爬滚打的码农一枚,对技术充满热情的菜鸟,致力为手Q的建设添砖加瓦.” 1.GIF格式的历史 GIF ( Gr ...
- Unity 重要基础知识点
这是两个月前的学习记录,发出来了下,如果有误欢迎大家指出: 脚本生命周期 //每当脚本被加载时调用一次 // 1. 在Awake中做一些初始化操作 void Awake(){ //初始化publi ...
- 堆栈指针 ---delete 使用
对拥有堆中一个有效对象的地址的指针进行删除操作的结果,是将这个堆内存的状态从“使用中” 变为“可用”(此时的可用就是指可以调用内存)释放了,可以再次覆盖此处;; 对指针内存进行删除操作后,指针 ...
- I帧 B帧 p帧 IDR帧的区别
转自:http://blog.csdn.net/sphone89/article/details/8086071 IDR(Instantaneous Decoding Refresh)--即时解码刷新 ...
- 论Collision Detection的作用
今天有空就仔细研究了一下Collision Detection的问题,以前总是弄不明白Continuous和Continuous Dynamic到底有什么区别,今天算是彻底弄明白了,官方文档说的太晦涩 ...
- [原]Unity3D深入浅出 - 物理引擎之刚体部件(Rigidbody)
在虚拟世界中,任何物体都是没有活力的,要想变的真实,Rigidbody是必不可少的组件,下面介绍Rigidbody的各个属性: Mass:质量 Drag:阻力,对象在运动时遇到的空气阻力,0表示没有空 ...
- iOS-直播开发(开发从底层做起)
一直在忙, 也没写过几次播客! 但一直热衷于直播开发技术, 公司又不是直播方向的, 所以就年前忙里偷袭研究了一下直播开发, 然后翻阅了很多大神的技术博客等, 写了一个简单的Demo, 又根据网上大神们 ...
- 浓缩的才是精华:浅析GIF格式图片的存储和压缩
成文迪, 在Web前端摸爬滚打的码农一枚,对技术充满热情的菜鸟,致力为手Q的建设添砖加瓦. GIF格式的历史 GIF(Graphics Interchange Format)原义是"图像互换 ...
随机推荐
- 小白对异步IO的理解
前言 看到越来越多的大佬都在使用python的异步IO,协程等概念来实现高效的IO处理过程,可是我对这些概念还不太懂,就学习了一下. 因为是初学者,在理解上有很多不到位的地方,如果有错误,还希望能够有 ...
- 第一章 UNIX 基础知识
1.1 Unix体系结构 OS定义为一种软件,它控制计算机硬件资源,提供程序运行环境,一般称其为内核(kernel),它体积小,位于环境中心. 内核的接口为系统调用(system call),共用函数 ...
- Leetcode 337. 打家劫舍 III
题目链接 https://leetcode.com/problems/house-robber-iii/description/ 题目描述 在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可 ...
- JVM——九大工具助你玩转Java性能优化
本文转载自 http://www.importnew.com/12324.html 本文由 ImportNew - 陈 晓舜 翻译自 idrsolutions.欢迎加入翻译小组.转载请参见文章末尾的要 ...
- USACO Section1.5 Prime Palindromes 解题报告
pprime解题报告 —— icedream61 博客园(转载请注明出处)--------------------------------------------------------------- ...
- day-python入门3
本节内容 鸡汤.电影 IDE介绍 知识回顾 数据类型 For循环 while循环 列表及常用操作 IDE介绍 IDE即集成开发环境 常见IDE Visualstudio : w ...
- 孤荷凌寒自学python第五十天第一次接触NoSql数据库_Firebase
孤荷凌寒自学python第五十天第一次接触NoSql数据库_Firebase (完整学习过程屏幕记录视频地址在文末) 之前对关系型数据库的学习告一段落,虽然能力所限没有能够完全完成理想中的所有数据库操 ...
- 孤荷凌寒自学python第四十天python 的线程锁RLock
孤荷凌寒自学python第四十天python的线程锁RLock (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 因为研究同时在多线程中读写同一个文本文件引发冲突,所以使用Lock锁尝试同步, ...
- CS231n——图像分类(KNN实现)
图像分类 目标:已有固定的分类标签集合,然后对于输入的图像,从分类标签集合中找出一个分类标签,最后把分类标签分配给该输入图像. 图像分类流程 输入:输入是包含N个图像的集合,每个图像的标签是K ...
- [转]Android的网络与通信
本文转自:http://www.cnblogs.com/qingblog/archive/2012/06/15/2550735.html 第一部分 Android网络基础 Android平台浏览器 ...