题意:就是相当于动规里面的求最大连续子串,不同的是,这里需要读入一个区间x,y,输出的区间 a,b 且x<=a<=b<=y,使得a b的连续子串最长,而且询问次数达到了10的五次方。

我是在大白书上看到这个题,一开始想简单了,就照着刘汝佳的思路写,线段树里只存了前缀最大和,后缀最大和,总最大和,但题目要求输出区间,明显的需要添加记录维护区间位置的,而且不止要存储 a,b,还要存pre suf,前缀 后缀的边界位置。我第一次写的时候意识到了,但是那个时候已经有点混乱了,我以为在查询的时候,根据最大和就能确定区间。。。结果真是。。。智商被碾压。

还有个令人心酸的地方,直接导致我WA了整整一版,。。。尼玛,我记得校队选拔赛的时候也是同样的问题卡了我最后一个简单的题目,就是我用的中间变量暂存最大和,我知道最大和肯定会超过int,所以之前就设置了ll,但尼玛我定义中间变量的时候,居然下意识还是用的int。。。。。检查了我N多遍才查出来。。尼玛太心酸了。。一定要注意细节

#include <iostream>
#include <cstdio>
#include <cstring>
#define Lson x<<1,l,mid
#define Rson (x<<1|1),mid+1,r
#define N 500030
using namespace std; struct node//线段树节点只需要记录前缀最右边间位置pre,类似的后缀suf,以及真正的解区间,vx,vy
{
int vx,vy;
int suf,pre;
} tree[N*];
long long s[N];
void getup(int x,int l,int r)
{
if (s[tree[x<<].pre]-s [l-]>=s[tree[x<<|].pre]-s[l-]){
tree[x].pre=tree[x<<].pre;
}
else{
tree[x].pre=tree[x<<|].pre;
}
if (s[r]-s[tree[x<<].suf-]>=s[r]-s[tree[x<<|].suf-]){
tree[x].suf=tree[x<<].suf;
}
else{
tree[x].suf=tree[x<<|].suf;
}
long long v1=s[tree[x<<].vy]-s[tree[x<<].vx-];
long long v2=s[tree[x<<|].vy]-s[tree[x<<|].vx-];
long long v0=s[tree[x<<|].pre]-s[tree[x<<].suf-];
if (v1>=v2){
tree[x].vx=tree[x<<].vx;
tree[x].vy=tree[x<<].vy;
}
else{
tree[x].vx=tree[x<<|].vx;
tree[x].vy=tree[x<<|].vy;
}
if (v0==s[tree[x].vy]-s[tree[x].vx-]){
if (tree[x<<].suf<tree[x].vx){
tree[x].vx=tree[x<<].suf;
tree[x].vy=tree[x<<|].pre;
}
else if (tree[x<<].suf==tree[x].vx && tree[x<<|].pre<tree[x].vy){
tree[x].vy=tree[x<<|].pre;
}
}
if (v0>s[tree[x].vy]-s[tree[x].vx-]){
tree[x].vx=tree[x<<].suf;
tree[x].vy=tree[x<<|].pre;
} }
void build(int x,int l,int r)
{
if (l==r)
{
tree[x].pre=tree[x].suf=tree[x].vy=tree[x].vx=l;
return;
}
int mid=(l+r)/;
build(Lson);
build(Rson);
getup(x,l,r);
}
node query(int st,int e,int x,int l,int r)
{
if (st<=tree[x].vx && tree[x].vy<=e){
return tree[x];
}
int mid=(l+r)/;
if (st>mid){
return query(st,e,Rson);
}
if (e<=mid){
return query(st,e,Lson);
}
node a=query(st,e,Lson);
node b=query(st,e,Rson);
node c;
if (s[a.vy]-s[a.vx-]>=s[b.vy]-s[b.vx-]){
c.vx=a.vx;
c.vy=a.vy;
}
else {
c.vx=b.vx;
c.vy=b.vy;
}
if (s[a.pre]-s[st-]>=s[b.pre]-s[st-]){
c.pre=a.pre;
}
else{
c.pre=b.pre;
}
if (s[e]-s[a.suf-]>=s[e]-s[b.suf-]){
c.suf=a.suf;
}
else{
c.suf=b.suf;
}
if (s[b.pre]-s[a.suf-]==s[c.vy]-s[c.vx-]){
if (a.suf<c.vx){
c.vx=a.suf;
c.vy=b.pre;
}
if (a.suf==c.vx && b.pre<c.vy){
c.vy=b.pre;
}
}
else
if (s[b.pre]-s[a.suf-]>s[c.vy]-s[c.vx-]){
c.vx=a.suf;
c.vy=b.pre;
}
return c;
}
int main()
{
int n,m;
int counts=;
while (scanf("%d%d",&n,&m)!=EOF)
{
int i,j,k;
memset(s,,sizeof s);
long long tt;
for (i=;i<=n;i++){
scanf("%lld",&tt);
s[i]=s[i-]+tt;
}
build(,,n);
printf("Case %d:\n",++counts);
for (i=;i<=m;i++){
int ss,e;
scanf("%d%d",&ss,&e);
node ans=query(ss,e,,,n); printf("%d %d\n",ans.vx,ans.vy);
}
}
return ;
}

经典线段树 UVALive 3938/UVA 1400的更多相关文章

  1. ZOJ - 1610 经典线段树染色问题

    这个是一个经典线段树染色问题,不过题目给的是左右左右坐标,即[0,3]包含0-1这一段 1-2这一段 2-3这一段,和传统的染色不太一样,不过其实也不用太着急. 我们把左边的坐标+1,即可,那么[0, ...

  2. pku 2777(经典线段树染色问题)

    Count Color Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 41202   Accepted: 12458 Des ...

  3. poj-2828 Buy Tickets(经典线段树)

    /* Buy Tickets Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 10207 Accepted: 4919 Descr ...

  4. poj 2528 poster经典线段树+lazy+离散化

    #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ; #def ...

  5. ZOJ1610(经典线段树涂色问题)

    Description Painting some colored segments on a line, some previously painted segments may be covere ...

  6. poj Hotel 线段树

    经典线段树的题. 每个节点存储的信息:左端点连续空房间的长度,右端点连续空房间长度,连续空房间的最大长度. 由于要求每次必须从尽量靠左边的位置进行居住,那么搜索时应尽量让区间起始位置更小: 1.如果当 ...

  7. 『zkw线段树及其简单运用』

    阅读本文前,请确保已经阅读并理解了如下两篇文章: 『线段树 Segment Tree』 『线段树简单运用』 引入 这是一种由\(THU-zkw\)大佬发明的数据结构,本质上是经典的线段树区间划分思想, ...

  8. 线段树模板hdu 1166:敌兵布阵

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  9. 线段树模板hdu 1754:I Hate It

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

随机推荐

  1. 《新标准C++程序设计》4.4(C++学习笔记14)

    运算符重载为友元函数 一般情况下,将运算符重载为类的成员函数,是较好的选择. 但有时,重载为成员函数不能满足使用要求,重载为普通函数,又不能访问类的私有成员,所以需要将运算符重载为友元. class ...

  2. java 图片上传

    代码是最有力量的,嘎嘎 @CrossOrigin@ApiOperation(value = "上传图片", notes = "上传图片", httpMethod ...

  3. delphi关闭和禁用Windows服务

    function StopServices(const SvrName: string): Boolean; var SCH, SvcSCH: SC_HANDLE; SS: TServiceStatu ...

  4. USB2.0主机控制器 UPD720114 简单详解

    UPD720114 是符合 USB 2.0规格的集线器控制器,适用于“符合生态原则的解决方案”.这种小型封装的控制器集成了核心逻辑电路的2.5 V 内部电压调整器.终端电阻器,减少了所需要的外部组件的 ...

  5. 微信小程序调用用百度地图天气功能

    #小程序之调用百度地图天气功能 本篇博客主要介绍小程序在百度地图中获取天气信息,如有不全请指出.下面先上效果图 主要内容 百度地图API的个人密钥,也就是AK 请求百度地图API接口数据 获取到的信息 ...

  6. 四十六、SAP的Message中E和W区别

    一.如果写的是E,则报红色的信息,如图 效果如下 二.如果是写的是W,则报黄色的信息 效果如下

  7. Elasticsearch 搜索数据

    章节 Elasticsearch 基本概念 Elasticsearch 安装 Elasticsearch 使用集群 Elasticsearch 健康检查 Elasticsearch 列出索引 Elas ...

  8. hdu 1257 最少拦截系统 求连续递减子序列个数 (理解二分)

    最少拦截系统 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  9. 中国移动携手华为百度展示5G应用,实现8K视频传输

    在今日举行的 2019 年百度云智峰会上,中国移动携手华为和百度,首次展示基于 SA 架构的 5G Vertical LAN (行业局域网)技术,承载 8K 实时会议系统,助力企业云办公.该技术可为合 ...

  10. PHP日期函数

    在正式学习日期函数前大家得了解几个概念: 1.时区 2.世界时 3.unix时间戳 时区 这个概念,之前大家听说过很多.我们来啰嗦两句,我们现实生活中使用的实区,在电脑里面也是一样有规定的.1884年 ...