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 ...
随机推荐
- IIS 无法访问.net的动态文件
编译器错误消息:CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework64\v4.0.30319... 在“c:\windows\temp”这个文件夹添 ...
- Array.prototype.forEach数组遍历
forEach是Array新方法中最基本的一个,就是遍历,循环.先看以前是怎么遍历数组的 常用遍历 var arr = [1,2,3,4,5]; for(var i = 0; i < arr.l ...
- Add a try-catch with Mono Cecil
Adding exception handlers with Mono.Cecil is not difficult, it just requires you to know how excepti ...
- 【BZOJ4144】[AMPPZ2014]Petrol 最短路+离线+最小生成树
[BZOJ4144][AMPPZ2014]Petrol Description 给定一个n个点.m条边的带权无向图,其中有s个点是加油站. 每辆车都有一个油量上限b,即每次行走距离不能超过b,但在加油 ...
- git add -A和git add . 的区别
git add -A和 git add . git add -u在功能上看似很相近,但还是有所差别. git add . :他会监控工作区的状态树,使用它会把工作时的所有变化提交到暂存区,包括文件内容 ...
- angularJS中的MVC思想?
mvc 思想: 将应用程序的组成,划分为三个部分:model , controller 和 view ; - 控制器的作用是用来初始化模型用的: - 模型就是用于存储数据的: - 视图是展示数据的: ...
- Linux--vim编辑器和文件恢复
第五章 Vim编辑器和恢复ext4下误删除的文件-Xmanager工具 本节所讲内容: 5.1 vim的使用 5.2 实战:恢复ext4文件系统下误删除的文件 5.3 实战:使用xmanage ...
- Haskell中cabal install glib遇到的问题
1. 运行命令cabal install glib时出现错误: Cannot find gtk2hsC2hs Please install `gtk2hs-buildtools` first and ...
- ubuntu16.04下安装opencv-3.1.0及其扩展模块opencv_contrib
步骤1.安装依赖项 sudo apt--dev pkg-config libavcodec-dev libavformat-dev libswscale-dev 可选的 sudo apt--dev l ...
- Information:java: Errors occurred while compiling module 'spring'
IntellJ Idea遇到Errors occurred while compiling module的解决方法 - sully2008的专栏 - CSDN博客 https://blog.csdn. ...