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. CSSOM视图模式(CSSOM View Module)

    一.Window视图属性(window对象) 这些属性可以获取住整个浏览器窗体大小.微软则将这些API称为“Screenview 接口” innerWidth 属性和 innerHeight 属性pa ...

  2. 高中生的IT之路-1.1自序

        近几年来越来越多的人问我关于 高中生要不要读大学.大学选择专业.毕业后的择业问题,索性我不如把我对这几方面的理解写出来,如果有幸能帮助到更多的人,那也算是个人对社会做出了一点贡献.       ...

  3. Oracle自动备份脚本的实现

    问题描述: Oracle自动备份脚本的实现. 错误提示1: Message file RMAN.msb not found Verify that Oracle_HOME is set properl ...

  4. 聊一聊goroutine stack

    通过阅读这篇文章对内存的处理以及栈的扩容有了新的认识,我们在生产环境中也遇到了内存使用量超大的情况,现在怀疑也可能是由于栈扩容导致的 很好的一片文章: 推送在外卖订餐中扮演着重要的角色,为商家实时接单 ...

  5. jquery ztree 刷新后记录折叠、展开状态

    ztree :http://www.ztree.me/v3/main.php 项目中用到了这个插件,刚好也有需求 在页面刷新后,保存开始的展开.折叠状态, 其实 dtree: http://www.d ...

  6. PHP面向对象详解:继承、封装与多态

    首先,在解释面向对象之前先解释下什么是面向对象? [面向对象]1.什么是类? 具有相同属性(特征)和方法(行为)的一系列个体的集合,类是一个抽象的概念2.什么是对象?从类中拿到的具有具体属性值得个体, ...

  7. toml-lang - Tom's Obvious, Minimal Language

    Tom's Obvious, Minimal Languagehttps://github.com/toml-lang/toml

  8. JavaScript如何把字符串中每个单词首字母转化为大写

    先上代码,再做解释. 思路分析: 1. 首先先把字符串中的单词转化为小写(toLowerCase),再对其进行截取(split),截取依据为按照空格截取: 2. 此时经过步骤一之后得到的东西是一个数组 ...

  9. Spring boot maven 搭建框架

    Spring Boot:目的:这个框架帮助开发者更容易地创建基于Spring的应用程序和服务,使得pring开发者能够最快速地获得所需要的Spring功能.优点:完全不需要XML配置,让spring应 ...

  10. 用 node.js 的 hexo 框架搭建一个支持 markdown 的静态博客系统

    1,Hexo如何在线可视化写博客:   可以试试这款插件 hexo-admin. 2,马克飞象:   一个非常好的 markdown 编辑器. 3,Hexo博客文章设置密码的方法: 首先,在Hexo中 ...