"Ray, Pass me the dishes!"
uvaLive3938:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1939
题意:给你n个数,然后给你一个区间,让你查询这个区间内最大和连续子区间。
题解:哎。智商是硬伤啊,虽然线段树也做过不少题目,但是遇到这样的题目还是不会处理啊,看了别人的代码才明白了怎么做。用那个线段树维护区间最大前缀,最大后缀,以及真正的最大区间。要注意父节点这三个变量是怎么由子节点推导出来的。还是贴代码吧。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=;
int ll[N*],rr[N*];
struct Node{
int pre,suf;
int vx,vy;
}num[N*];
long long sum[N];
void pushup(int rt,int l,int r){
if(sum[num[rt<<].pre]-sum[l-]>=sum[num[rt<<|].pre]-sum[l-])
num[rt].pre=num[rt<<].pre;
else
num[rt].pre=num[rt<<|].pre;
if(sum[r]-sum[num[rt<<].suf-]>=sum[r]-sum[num[rt<<|].suf-])
num[rt].suf=num[rt<<].suf;
else
num[rt].suf=num[rt<<|].suf;
long long v1=sum[num[rt<<].vy]-sum[num[rt<<].vx-];
long long v2=sum[num[rt<<|].vy]-sum[num[rt<<|].vx-];
long long v0=sum[num[rt<<|].pre]-sum[num[rt<<].suf-];
if(v1>=v2){
num[rt].vx=num[rt<<].vx;
num[rt].vy=num[rt<<].vy;
}
else{
num[rt].vx=num[rt<<|].vx;
num[rt].vy=num[rt<<|].vy;
}
if(v0==sum[num[rt].vy]-sum[num[rt].vx-]){
if(num[rt<<].suf<num[rt].vx){
num[rt].vx=num[rt<<].suf;
num[rt].vy=num[rt<<|].pre;
}
}
if(v0>sum[num[rt].vy]-sum[num[rt].vx-]){
num[rt].vx=num[rt<<].suf;
num[rt].vy=num[rt<<|].pre;
}
}
void build(int rt,int l,int r){
ll[rt]=l;
rr[rt]=r;
if(l==r){
num[rt].pre=num[rt].suf=num[rt].vx=num[rt].vy=l;
return;
}
int mid=(l+r)/;
build(rt<<,l,mid);
build(rt<<|,mid+,r);
pushup(rt,l,r);
}
Node query(int rt,int s,int t){
if(ll[rt]==s&&rr[rt]==t)
return num[rt];
int mid=(ll[rt]+rr[rt])/;
if(mid>=t)return query(rt<<,s,t);
else if(mid<s)return query(rt<<|,s,t);
else{
Node temp1=query(rt<<,s,mid);
Node temp2=query(rt<<|,mid+,t);
Node temp;
if(sum[temp1.pre]-sum[s-]>=sum[temp2.pre]-sum[s-])
temp.pre=temp1.pre;
else
temp.pre=temp2.pre;
if(sum[t]-sum[temp1.suf-]>=sum[t]-sum[temp2.suf-])
temp.suf=temp1.suf;
else
temp.suf=temp2.suf;
long long v1=sum[temp1.vy]-sum[temp1.vx-];
long long v2=sum[temp2.vy]-sum[temp2.vx-];
long long v0=sum[temp2.pre]-sum[temp1.suf-];
if(v1>=v2){
temp.vx=temp1.vx;
temp.vy=temp1.vy;
}
else{
temp.vx=temp2.vx;
temp.vy=temp2.vy;
}
if(v0==sum[temp.vy]-sum[temp.vx-]){
if(temp1.suf<temp.vx){
temp.vx=temp1.suf;
temp.vy=temp2.pre;
}
}
if(v0>sum[temp.vy]-sum[temp.vx-]){
temp.vx=temp1.suf;
temp.vy=temp2.pre;
}
return temp;
}
}
int main(){
int cas=,n,m,l,r;
long long tp;
while(~scanf("%d%d",&n,&m)){
memset(sum,,sizeof(sum));
for(int i=;i<=n;i++){
scanf("%lld",&tp);
sum[i]=sum[i-]+tp;
}
build(,,n);
printf("Case %d:\n",++cas);
for(int i=;i<=m;i++){
scanf("%d%d",&l,&r);
Node ans=query(,l,r);
printf("%d %d\n",ans.vx,ans.vy);
}
} }
"Ray, Pass me the dishes!"的更多相关文章
- UvaLA 3938 "Ray, Pass me the dishes!"
"Ray, Pass me the dishes!" Time Limit: 3000MS Memory Limit: Unkn ...
- UVA 1400."Ray, Pass me the dishes!" -分治+线段树区间合并(常规操作+维护端点)并输出最优的区间的左右端点-(洛谷 小白逛公园 升级版)
"Ray, Pass me the dishes!" UVA - 1400 题意就是线段树区间子段最大和,线段树区间合并,但是这道题还要求输出最大和的子段的左右端点.要求字典序最小 ...
- UVA 1400 1400 - "Ray, Pass me the dishes!"(线段树)
UVA 1400 - "Ray, Pass me the dishes!" option=com_onlinejudge&Itemid=8&page=show_pr ...
- 【LA3938】"Ray, Pass me the dishes!"
原题链接 Description After doing Ray a great favor to collect sticks for Ray, Poor Neal becomes very hun ...
- 线段树(区间合并) LA 3989 "Ray, Pass me the dishes!"
题目传送门 题意:动态最大连续子序列和,静态的题目 分析:nlogn的归并思想.线段树维护结点的三个信息,最大前缀和,最大后缀和,该区间的最大和的两个端点,然后答案是三个的better.书上用pair ...
- UVa 1400 (线段树) "Ray, Pass me the dishes!"
求一个区间的最大连续子序列,基本想法就是分治,这段子序列可能在区间的左半边,也可能在区间的右半边,也有可能是横跨区间中点,这样就是左子区间的最大后缀加上右子区间的最大前缀之和. 线段树维护三个信息:区 ...
- 1400 - "Ray, Pass me the dishes!"
哈哈,原来题意看错了,但有多个解的时候,输出起点靠前的,如果起点一样,则输出终点靠前的,修改后AC的代码如下: #include <cstdio> #include <iostrea ...
- uvalive 3938 "Ray, Pass me the dishes!" 线段树 区间合并
题意:求q次询问的静态区间连续最大和起始位置和终止位置 输出字典序最小的解. 思路:刘汝佳白书 每个节点维护三个值 pre, sub, suf 最大的前缀和, 连续和, 后缀和 然后这个题还要记录解的 ...
- uva 1400 - "Ray, Pass me the dishes!"
又是一道线段树区间更新的题: #include<cstdio> #include<algorithm> #include<cstring> #define ll l ...
随机推荐
- [React + Mobx] Mobx and React intro: syncing the UI with the app state using observable and observer
Applications are driven by state. Many things, like the user interface, should always be consistent ...
- SQL Server未找到或无法訪问server问题解决
问题信息:"在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误.未找到或无法訪问服务器.请验证实例名称是否正确而且 SQL Server 已配置为同意远程连接. (pr ...
- linux下daemon守护进程的实现(以nginx代码为例)
ngx_int_t ngx_daemon(ngx_log_t *log) { int fd; // 让init进程成为新产生进程的父进程: // 调用fork函数创建子进程后,使父进程立即退出.这样, ...
- [转]Flex 布局教程:语法篇
网页布局(layout)是CSS的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂直居中 ...
- MySQL存储过程学习笔记
MySQL在5.0以前并不支持存储过程,这使得MySQL在应用上大打折扣.MySQL 5.0终于开始支持存储过程了. MySQL的关键字大小写通用.该学习笔记对关键字使用大写:变量名,表名使用小写. ...
- U3D 脚本添加和获得对象
有时候,一开始可能没有对象,而是由于某种触发,产生的一个对象,这里讲解下,如何通过脚本来创建一个对象: 这是通过脚本创建一个立方体: using UnityEngine; using System.C ...
- android 如何解决模块之间的通讯的耦合问题
使用EventBus http://wuyexiong.github.io/blog/2013/04/30/android-fragment/ http://yunfeng.sinaapp.com/? ...
- Encapsulation.
Access control is often referred to as implementation hiding. Wrapping data and methods within class ...
- UISearchBar 光标不出现的问题
app支持ios7,在UINavBar 里面加入搜索框,结果光标一直出现不了. 解决办法如下: searchBar.tintColor = [UIColor blueColor];
- 移动端touchstar、touchmove、touchend 事件如果页面有滚动时不让触发 touchend 事件。
/*仅适用于内容中点击元素.对于拖动等元素,需要自行在页面处理. * 主要是绑定touchstart和touchmove事件,并判断用户按下之后手指移动了多少像素. * 如果手指移动距离小于10像素, ...