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 ListView基本用法大全

    //增加项或列(字段) ListView1.Clear; ListView1.Columns.Clear; ListView1.Columns.Add; ListView1.Columns.Add; ...

  2. nginx 笔记

    nginx 这个轻量级.高性能的 web server 主要可以干两件事情: 〉直接作为http server(代替apache,对PHP需要FastCGI处理器支持): 〉另外一个功能就是作为反向代 ...

  3. [转] Mac 下 PostgreSQL 的安装与使用

    在 mac 下,可以利用 homebrew 直接安装 PostgreSQL: 1 brew install postgresql -v 稍等片刻,PostgreSQL 就安装完成.接下来就是初始数据库 ...

  4. QT Windows下生成动态链接库

    目标:需要将一个QT程序生成动态链接库 Windows环境下Qt生成的共享库文件其后缀为dll,可以在程序运行过程中动态加载 新建项目,选择库 选择共享库 建立好项目后生成三个文件,两个.h一个.cp ...

  5. noip 2003 传染病控制(历史遗留问题2333)

    /*codevs 1091 搜索 几个月之前写的70分 今天又写了一遍 并且找到了错误 */ #include<cstdio> #include<vector> #define ...

  6. C# GridView点击某列打开新浏览器窗口

    C# GridView点击某列打开新窗口的方式: (1)打开浏览器新窗口:蓝色部分 通过超链接. (2)打开模式化窗口:通过OnRowCommand事件,弹出模式化窗口. 具体如下: <asp: ...

  7. java异常类的使用

    1.异常的概念 什么是异常?程序出错分为两部分,编译时出粗和运行时出错.编译时出错是编译器在编译源码时发生的错误: 运行时出错是在编译通过,在运行时出现的错误.这种情况叫异常. 例如:数组越界,除数为 ...

  8. oracle数据表误删恢复

    1.查看回收站中的表: select object_name,original_name,partition_name,type,ts_name,createtime,droptime from re ...

  9. iOS中MVVM的架构设计与团队协作

    对MVVM的理解主要是借鉴于之前的用过的MVC的Web框架,之前用过ThinkPHP框架,和SSH框架,都是MVC的架构模式,今天MVVM与传统的MVC可谓是极为相似,也可以说是兄弟关系,也就是一家人 ...

  10. VisualStudio2013&VS2015内置SQLServer入门 (三)

    关于LocalDB的部署(publish): 使用本机做服务器(目测不可行) 双击项目的Properties-->Publish-->Application Files,你会发现没有.md ...