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!"的更多相关文章

  1. UvaLA 3938 "Ray, Pass me the dishes!"

                            "Ray, Pass me the dishes!" Time Limit: 3000MS   Memory Limit: Unkn ...

  2. UVA 1400."Ray, Pass me the dishes!" -分治+线段树区间合并(常规操作+维护端点)并输出最优的区间的左右端点-(洛谷 小白逛公园 升级版)

    "Ray, Pass me the dishes!" UVA - 1400 题意就是线段树区间子段最大和,线段树区间合并,但是这道题还要求输出最大和的子段的左右端点.要求字典序最小 ...

  3. UVA 1400 1400 - &quot;Ray, Pass me the dishes!&quot;(线段树)

    UVA 1400 - "Ray, Pass me the dishes!" option=com_onlinejudge&Itemid=8&page=show_pr ...

  4. 【LA3938】"Ray, Pass me the dishes!"

    原题链接 Description After doing Ray a great favor to collect sticks for Ray, Poor Neal becomes very hun ...

  5. 线段树(区间合并) LA 3989 "Ray, Pass me the dishes!"

    题目传送门 题意:动态最大连续子序列和,静态的题目 分析:nlogn的归并思想.线段树维护结点的三个信息,最大前缀和,最大后缀和,该区间的最大和的两个端点,然后答案是三个的better.书上用pair ...

  6. UVa 1400 (线段树) "Ray, Pass me the dishes!"

    求一个区间的最大连续子序列,基本想法就是分治,这段子序列可能在区间的左半边,也可能在区间的右半边,也有可能是横跨区间中点,这样就是左子区间的最大后缀加上右子区间的最大前缀之和. 线段树维护三个信息:区 ...

  7. 1400 - "Ray, Pass me the dishes!"

    哈哈,原来题意看错了,但有多个解的时候,输出起点靠前的,如果起点一样,则输出终点靠前的,修改后AC的代码如下: #include <cstdio> #include <iostrea ...

  8. uvalive 3938 "Ray, Pass me the dishes!" 线段树 区间合并

    题意:求q次询问的静态区间连续最大和起始位置和终止位置 输出字典序最小的解. 思路:刘汝佳白书 每个节点维护三个值 pre, sub, suf 最大的前缀和, 连续和, 后缀和 然后这个题还要记录解的 ...

  9. uva 1400 - "Ray, Pass me the dishes!"

    又是一道线段树区间更新的题: #include<cstdio> #include<algorithm> #include<cstring> #define ll l ...

随机推荐

  1. [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 ...

  2. SQL Server未找到或无法訪问server问题解决

    问题信息:"在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误.未找到或无法訪问服务器.请验证实例名称是否正确而且 SQL Server 已配置为同意远程连接. (pr ...

  3. linux下daemon守护进程的实现(以nginx代码为例)

    ngx_int_t ngx_daemon(ngx_log_t *log) { int fd; // 让init进程成为新产生进程的父进程: // 调用fork函数创建子进程后,使父进程立即退出.这样, ...

  4. [转]Flex 布局教程:语法篇

    网页布局(layout)是CSS的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂直居中 ...

  5. MySQL存储过程学习笔记

    MySQL在5.0以前并不支持存储过程,这使得MySQL在应用上大打折扣.MySQL 5.0终于开始支持存储过程了. MySQL的关键字大小写通用.该学习笔记对关键字使用大写:变量名,表名使用小写. ...

  6. U3D 脚本添加和获得对象

    有时候,一开始可能没有对象,而是由于某种触发,产生的一个对象,这里讲解下,如何通过脚本来创建一个对象: 这是通过脚本创建一个立方体: using UnityEngine; using System.C ...

  7. android 如何解决模块之间的通讯的耦合问题

    使用EventBus http://wuyexiong.github.io/blog/2013/04/30/android-fragment/ http://yunfeng.sinaapp.com/? ...

  8. Encapsulation.

    Access control is often referred to as implementation hiding. Wrapping data and methods within class ...

  9. UISearchBar 光标不出现的问题

    app支持ios7,在UINavBar 里面加入搜索框,结果光标一直出现不了. 解决办法如下: searchBar.tintColor = [UIColor blueColor];

  10. 移动端touchstar、touchmove、touchend 事件如果页面有滚动时不让触发 touchend 事件。

    /*仅适用于内容中点击元素.对于拖动等元素,需要自行在页面处理. * 主要是绑定touchstart和touchmove事件,并判断用户按下之后手指移动了多少像素. * 如果手指移动距离小于10像素, ...