https://vjudge.net/problem/UVALive-3938

题意:
给出一个长度为n的整数序列D,你的任务是对m个询问作出回答。对于询问(a,b),需要找到两个下标x和y,使得a≤x≤y≤b,并且Dx+Dx+1+...+Dy尽量大。如果有多组满足条件的x和y,x应该尽量小。如果还有多解,y应该尽量小。

思路:
线段树。

这道题目挺麻烦的,也是参考了刘汝佳的代码。

 #include<iostream>
#include<cstring>
#include<algorithm>
using namespace std; const int maxn = + ;
typedef pair<int, int> Interval; int n, m;
long long sum[maxn];
int QL, QR; struct node
{
Interval max_sub; //最大连续和
int max_prefix; //最大前缀和
int max_suffix; //最大后缀和
}t[maxn]; long long cacl(int L, int R)
{
return sum[R] - sum[L - ];
} Interval better(Interval a, Interval b)
{
if (cacl(a.first, a.second) != cacl(b.first, b.second))
return cacl(a.first, a.second) > cacl(b.first, b.second) ? a : b;
return a < b ? a : b;
} void build_tree(int L, int R, int k)
{
if (L == R)
{
t[k].max_prefix = L;
t[k].max_suffix = L;
t[k].max_sub = make_pair(L, L);
return;
}
else
{
int mid = (L + R) / ;
int lc = * k, rc = * k + ;
build_tree(L, mid, lc);
build_tree(mid + , R, rc); //计算最大前缀和
long long x1 = cacl(L, t[lc].max_prefix);
long long x2 = cacl(L, t[rc].max_prefix);
if (x1 == x2) t[k].max_prefix = min(t[lc].max_prefix, t[rc].max_prefix);
else t[k].max_prefix = x1 > x2 ? t[lc].max_prefix : t[rc].max_prefix; //计算最大后缀和
x1 = cacl(t[lc].max_suffix, R);
x2 = cacl(t[rc].max_suffix, R);
if (x1 == x2) t[k].max_suffix = min(t[lc].max_suffix, t[rc].max_suffix);
else t[k].max_suffix = x1 > x2 ? t[lc].max_suffix : t[rc].max_suffix; //计算最大连续和
t[k].max_sub = better(t[lc].max_sub, t[rc].max_sub);
t[k].max_sub = better(t[k].max_sub, make_pair(t[lc].max_suffix, t[rc].max_prefix));
}
} Interval query_suffix(int L, int R, int k)
{
if (t[k].max_suffix >= QL) return make_pair(t[k].max_suffix, R);
int mid = (L + R) / ;
int lc = * k, rc = * k + ;
if (QL > mid) return query_suffix(mid + , R, rc);
Interval x = query_suffix(L, mid, lc);
x.second = R;
return better(x, make_pair(t[rc].max_suffix, R));
} Interval query_prefix(int L, int R, int k)
{
if (QR >= t[k].max_prefix) return make_pair(L, t[k].max_prefix);
int mid = (L + R) / ;
int lc = * k, rc = * k + ;
if (QR <= mid) return query_prefix(L, mid, lc);
Interval x = query_prefix(mid + , R, rc);
x.first = L;
return better(x, make_pair(L, t[lc].max_prefix));
} Interval query(int L, int R, int k)
{
if (QL <= L && QR >= R) return t[k].max_sub;
int mid = (L + R) / ;
int lc = * k;
int rc = * k + ;
if (QR <= mid) return query(L, mid, lc); //完全在左半段
if (QL > mid) return query(mid + , R, rc); //完全在右半段
Interval x1 = query_suffix(L, mid, lc); //左半段的后缀
Interval x2 = query_prefix(mid + , R, rc); //右半段的前缀
Interval x3 = better(query(L, mid, lc), query(mid + , R, rc));
return better(make_pair(x1.first, x2.second), x3);
} int main()
{
//freopen("D:\\txt.txt", "r", stdin);
int x;
int kase = ;
while (~scanf("%d%d", &n, &m))
{
sum[] = ;
for (int i = ; i <= n; i++)
{
scanf("%d", &x);
sum[i] = sum[i - ] + x;
}
build_tree(, n, );
printf("Case %d:\n", ++kase);
while (m--)
{
scanf("%d%d", &QL, &QR);
Interval ans = query(, n, );
printf("%d %d\n", ans.first, ans.second);
}
}
}

LA 3938 动态最大连续和(线段树)的更多相关文章

  1. LA 3938 动态最大连续和 线段树

    题目链接: https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show ...

  2. LA 3938 动态最大连续和

    题目链接:https://vjudge.net/contest/146667#problem/C 题意:动态的求一个区间的最大连续和. 分析: 看上去可以RMQ去做,但是,当分成两个部分,原来的部分的 ...

  3. 【BZOJ3295】动态逆序对(线段树,树状数组)

    [BZOJ3295]动态逆序对(线段树,树状数组) 题面 Description 对于序列A,它的逆序对数定义为满足iAj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的 ...

  4. 指针-动态开点&合并线段树

    一个知识点不在一道题里说是没有灵魂的 线段树是用来处理区间信息的咯 但是往往因为需要4倍空间让许多人退却,而动态开点的线段树就非常棒 仿佛只用2倍就可以咯 指针保存位置,即节点信息,是很舒适的,所以用 ...

  5. BZOJ 4636 (动态开节点)线段树

    思路: 偷懒 懒得离散化 搞了个动态开节点的线段树 (其实是一样的--..) 注意会有a=b的情况 要判掉 //By SiriusRen #include <cstdio> #includ ...

  6. 【最长连续零 线段树】bzoj1593: [Usaco2008 Feb]Hotel 旅馆

    最长连续零的线段树解法 Description 奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光.作为整个旅游的策划者和负 责人,贝茜选择在湖边的一家著名的旅馆住宿.这个巨大 ...

  7. zoj 2112 Dynamic Rankings 动态第k大 线段树套Treap

    Dynamic Rankings Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.zju.edu.cn/onlinejudge/show ...

  8. UVA_12697 满足条件的最短连续和 线段树维护

    好印象深刻的题,前天选拔赛给跪了.怪我这种关键题没敲出来. 题意很简单,给你一串无规则的数列,再给个m值,求出满足 数列和>=m的长度最小的连续子串...确实一开始卡住了,因为看数据肯定是nlo ...

  9. AcWing1264. 动态求连续区间和 (线段树做法)

    1.题目 给定 n 个数组成的一个数列,规定有两种操作,一是修改某个元素,二是求子数列 [a,b] 的连续和. 输入格式 第一行包含两个整数 n 和 m,分别表示数的个数和操作次数. 第二行包含 n ...

随机推荐

  1. interface Impl

    public interface ActionBarOperations { void initSthOne(); void initSthTwo(); } public class ActionBa ...

  2. 输入一个网站地址到网站展现的过程以及APR协议(鬼知道中间经历了什么)

    以前只知道输入一个网站,然后看着返回琳琅满目的内容,其实中间经历的过程和步骤太多了.为了满足好奇心以及学习需要,特查阅了资料将其记录下来以备后续自己复习. 从我在地址栏输入www.zhihu.com ...

  3. C++ list容器系列功能函数详解

    C++ list函数详解 首先说下eclipse工具下怎样debug:方法:你先要设置好断点,然后以Debug方式启动你的应用程序,不要用run的方式,当程序运行到你的断点位置时就会停住,也会提示你进 ...

  4. 从零打造在线网盘系统之SSH框架整合

    欢迎浏览Java工程师SSH教程从零打造在线网盘系统系列教程,本系列教程将会使用SSH(Struts2+Spring+Hibernate)打造一个在线网盘系统,本系列教程是从零开始,所以会详细以及着重 ...

  5. JSP教程

    http://www.runoob.com/jsp/jsp-tutorial.html

  6. CentOS中为新用户添加sudo权限

    1.切换成root权限 su root 2.查看/etc/sudoers文件权限,如果只读权限,修改为可写权限 ls -l /etc/sudoers 3.如果是只读进行如下操作 chmod /etc/ ...

  7. CRM - 讲师与学生

    一.讲师与学生简介 1.初始化 course_record, study_record.2.学习记录3.录入成绩4.显示成绩 ajax 查询 柱状图展示成绩 highcharts 5.上传作业(os模 ...

  8. Qt 控制线程的顺序执行(使用QWaitCondition,并且线程类的run函数里记得加exec(),使得线程常驻)

    背景项目中用到多线程,对线程的执行顺序有要求: A.一个线程先收数据 B.一个线程处理数据 C.一个线程再将处理后的数据发送出去 要求三个线程按照ABC的顺序循环执行. 思路子类化多线程方法 重写子类 ...

  9. 《TP5.0学习笔记---模型篇》

    https://blog.csdn.net/self_realian/article/details/78596261 一.什么是模型 为什么我们要在项目中使用模型,其实我们知道,我们可以直接在控制器 ...

  10. luarocks模块管理工具

    1.简介 该软件包可以安装和更新lua的第三方模块. 2.下载地址 请在 http://luarocks.org/releases/ 页面选择需要的软件包. wget http://luarocks. ...