LA 3938 动态最大连续和(线段树)
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 动态最大连续和(线段树)的更多相关文章
- LA 3938 动态最大连续和 线段树
题目链接: https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show ...
- LA 3938 动态最大连续和
题目链接:https://vjudge.net/contest/146667#problem/C 题意:动态的求一个区间的最大连续和. 分析: 看上去可以RMQ去做,但是,当分成两个部分,原来的部分的 ...
- 【BZOJ3295】动态逆序对(线段树,树状数组)
[BZOJ3295]动态逆序对(线段树,树状数组) 题面 Description 对于序列A,它的逆序对数定义为满足iAj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的 ...
- 指针-动态开点&合并线段树
一个知识点不在一道题里说是没有灵魂的 线段树是用来处理区间信息的咯 但是往往因为需要4倍空间让许多人退却,而动态开点的线段树就非常棒 仿佛只用2倍就可以咯 指针保存位置,即节点信息,是很舒适的,所以用 ...
- BZOJ 4636 (动态开节点)线段树
思路: 偷懒 懒得离散化 搞了个动态开节点的线段树 (其实是一样的--..) 注意会有a=b的情况 要判掉 //By SiriusRen #include <cstdio> #includ ...
- 【最长连续零 线段树】bzoj1593: [Usaco2008 Feb]Hotel 旅馆
最长连续零的线段树解法 Description 奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光.作为整个旅游的策划者和负 责人,贝茜选择在湖边的一家著名的旅馆住宿.这个巨大 ...
- zoj 2112 Dynamic Rankings 动态第k大 线段树套Treap
Dynamic Rankings Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.zju.edu.cn/onlinejudge/show ...
- UVA_12697 满足条件的最短连续和 线段树维护
好印象深刻的题,前天选拔赛给跪了.怪我这种关键题没敲出来. 题意很简单,给你一串无规则的数列,再给个m值,求出满足 数列和>=m的长度最小的连续子串...确实一开始卡住了,因为看数据肯定是nlo ...
- AcWing1264. 动态求连续区间和 (线段树做法)
1.题目 给定 n 个数组成的一个数列,规定有两种操作,一是修改某个元素,二是求子数列 [a,b] 的连续和. 输入格式 第一行包含两个整数 n 和 m,分别表示数的个数和操作次数. 第二行包含 n ...
随机推荐
- 真机远程页面调试工具spy-debugger 3.x:集成weinre+AnyProxy,页面调试+抓包。调试生产HTTPS页面。
.页面调试+抓包 2.操作简单 3.支持HTTPS. 4.spy-debugger内部集成了weinre.node-mitmproxy.AnyProxy. 5.自动忽略原生App发起的https请求, ...
- 【BZOJ2946】[Poi2000]公共串 后缀数组+二分
[BZOJ2946][Poi2000]公共串 Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l 读入单词 l 计 ...
- 【BZOJ2453】维护队列/【BZOJ2120】数颜色 分块
[BZOJ2453]维护队列 Description 你小时候玩过弹珠吗? 小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N.为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色 ...
- 微信小程序 --- if/else条件渲染
if 条件渲染:当为真的时候显示,当为假的时候隐藏: else 条件渲染:当为真的时候隐藏,当为假的时候显示: <view wx:if="{{true}}">{{tex ...
- CH601后缀数组【Trie树】
内含字典树创建及查询模板 1601 前缀统计 0x10「基本数据结构」例题 描述 给定N个字符串S1,S2...SN,接下来进行M次询问,每次询问给定一个字符串T,求S1-SN中有多少个字符串是T的前 ...
- scribe、chukwa、kafka、flume日志系统对比
scribe.chukwa.kafka.flume日志系统对比 1. 背景介绍许多公司的平台每天会产生大量的日志(一般为流式数据,如,搜索引擎的pv,查询等),处理 这些日志需要特定的日志系统,一 ...
- vue - nodejs
一.知识 打开Nodejs英文网:https://nodejs.org/en/ 中文网:http://nodejs.cn/ 我们会发现这样一句话: 翻译成中文如下: Node.js 是一个基于 Chr ...
- python 定义类 学习1
此时的d1就是类Dog的实例化对象 实例化,其实就是以Dog类为模版,在内存里开辟一块空间,存上数据,赋值成一个变量名 # 定义类模板 class dog(object): # 定义类的方法功能 # ...
- php计算中英文混合或中文字符串的字数
转载来源链接: http://blog.csdn.net/hueise_h/article/details/22920937 php的strlen和mb_strlen用于统计字符个数.中英文混合的字符 ...
- 后台管理系统-使用AdminLTE搭建前端
返回总目录<ABP项目实战-后台管理系统-目录> 安装AdminLte 我们通过Nuget包管理器安装AdminLte 引用三方组件 因为AdminLte使用到了很多三方的组件,所以我们需 ...