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. Delphi十进制和十六进制互转

    Delphi 自带函数 IntToHex 功能说明:该函数用于将“十进制”转换成“十六进制”.该函数有二个参数.第一个参数为要转换的十进制数据,第二个参数是指定使用多少位来显示十六进制数据. 参考实例 ...

  2. [Javascript] Using JSHint for Linting with Gulp

    gulpfile.js var gulp = require('gulp'); var jshint = require('gulp-jshint'); var stylish = require(' ...

  3. 关于 Cocoa Pods 的使用

    前提:电脑上已经安装好CocoaPods. 创建Podfile: 1.进入到项目的目录中: $ cd 目录 2.使用终端命令行: $ vim Podfile 3.然后按i键,进入编辑模式 我现在使用的 ...

  4. fiddler了解

    常常听到有人会所抓包什么的,自己电脑上有一段fiddler软件,但是一直没有使用,因为不了解.今天终于看视频,看博客,大致了解了fiddler这个软件,看着是非常强大啊.那么fiddler到底是什么, ...

  5. app包中的fragment和v4包中的fragment的使用的区别

    app包中的fragment和v4包中的fragment的使用的区别 1.尽量不要用app包中的fragment,因为这个是在3.0之后才有的,支持的版本太高,在低版本中是是用不了的 2.androi ...

  6. Bootstrap Table的例子(转载)

    转载自:http://wenzhixin.net.cn/p/bootstrap-table/docs/examples.html#classes-table 使用的API: data1.json da ...

  7. 制作SSL证书

    上一节介绍了OpenSSL的目录结构,本节介绍一下SSL证书的制作. OpenSSL安装后建议把其中的bin目录添加到系统环境变量中,方便以后操作. 建立一个新的目录SSL专门用来制作证书. 建立证书 ...

  8. 使用Xcode插件,让iOS开发更加便捷

    在iOS开发过程中,写注释是一项必不可少的工作.这不仅有助于自己对代码整理回顾,而且提高了代码的可读性,让代码维护变得容易.但是,写注释又是一项枯燥的工作.我们浪费了大量的时间在输入/*,*,*/这样 ...

  9. NSNumber 转 NSString

    之前number 转string时候调用stringValue,后来发现未完全转 NSNumber * a_num = [NSNumber numberWithInteger: ]; NSString ...

  10. EMA计算的C#实现(c# Exponential Moving Average (EMA) indicator )

    原来国外有个源码(TechnicalAnalysisEngine src 1.25)内部对EMA的计算是: var copyInputValues = input.ToList(); for (int ...