bnuoj 27411 堆或单调队列维护区间RMQ

很显然n方的复杂度过不了。

于是考虑优化最值的查询,可以考虑用堆或者单调队列来做。

堆:

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <queue>
 5 using namespace std;
 6
 7 const int INF = 99999999;
 8 const int N = 32768;
 9 int a[N];
10 int n, l, u;
11
12 struct Node
13 {
14     int l;
15     int s;
16     Node () {}
17     Node ( int _l, int _s )
18     {
19         l = _l;
20         s = _s;
21     }
22     bool operator < ( const Node & t ) const
23     {
24         return s < t.s;
25     }
26 };
27
28 int solve()
29 {
30     priority_queue<Node> q;
31     int ans = INF;
32     for ( int i = l; i <= n; i++ )
33     {
34         q.push( Node ( i - l, a[i - l] ) );
35         while ( q.top().l + u < i ) q.pop();
36         int tmp = a[i] - q.top().s;
37         if ( tmp < ans ) ans = tmp;
38     }
39     return ans;
40 }
41
42 int main()
43 {
44     while ( scanf("%d", &n), n )
45     {
46         scanf("%d%d", &l, &u);
47         a[0] = 0;
48         for ( int i = 1; i <= n; i++ )
49         {
50             scanf("%d", a + i);
51             a[i] += a[i - 1];
52         }
53         printf("%d\n", solve());
54     }
55     return 0;
56 }

单调队列:

时间: 2024-12-15 07:09:44

bnuoj 27411 堆或单调队列维护区间RMQ的相关文章

[noi2013]快餐店 基环树dp,单调队列维护最大值和次大值

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 220000 #define inf 0x3ffffffffffffffLL typedef long long ll; int v[N],e[N],ne[N],nn,w[N]; void add(int x,int y,int z){ ne[++nn

bzoj1233: [Usaco2009Open]干草堆tower 单调队列优化dp

又是一道单调队列优化dp的题目 这道题呢 先要了解一个结论,在多种可行的堆叠方案中,至少有一种能使层数最高的方案同时使得底边最短.即底边最短的,层数一定最高. 这个是zkw大神得出的 我也不会证明来着 反正这样之后我们就可以得出正确的方法了 递推式 F[i]=min(sum[j-1]-sum[i-1])  j>i 且 sum[j-1]-sum[i-1]>=F[j] 易得在满足的条件下j当然是越小越好了嘛 而这样得出的方程又满足一定的单调性 这样调整之后队首就是我们要的答案啦 又对于转移条件 f

BZOJ 1342 Baltic2007 Sound静音问题 单调队列

题目大意:给定一个长度为n的序列,求哪些长度为m的区间满足区间内最大值与最小值之差小于等于c 利用单调队列维护区间内的最大值和最小值- - 硬搞就可以了- - 刷刷水题真爽- - #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 1001001 using namespace std; int n,m,c,a[M]; int q_ma

hdu3530 双单调队列的维护

单调队列有部分堆的功能,但其只能维护给定区间中比v大的值或者比v小的值,且其一般存储元素的下标. 思路:两个单调队列维护最大值与最小值的下标,如果区间的最大值最小值之差大于给定范围,则选择队首靠左的删去,并记录删去元素的下标,然后维护最大区间长度即可 注意有两个范围,第二个范围不能忽略 /* 单调队列存储区间最大值,最小值 如果Max-Min>k,呢么左端点靠前的删掉队头元素,删掉时记录下标 */ #include<iostream> #include<cstring> #i

单调队列 BZOJ 2096 [Poi2010]Pilots

2096: [Poi2010]Pilots Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 819  Solved: 418[Submit][Status][Discuss] Description Tz又耍畸形了!!他要当飞行员,他拿到了一个飞行员测试难度序列,他设定了一个难度差的最大值,在序列中他想找到一个最长的子串,任意两个难度差不会超过他设定的最大值.耍畸形一个人是不行的,于是他找到了你. Input 输入:第一行两个有空格隔开的整数k(0

【NOIP数据结构专项】单调队列单调栈

[洛谷P1901 ]发射站 http://www.luogu.org/problem/show?pid=1901 题目描述 某地有 N 个能量发射站排成一行,每个发射站 i 都有不相同的高度 Hi,并能向两边(当 然两端的只能向一边)同时发射能量值为 Vi 的能量,并且发出的能量只被两边最近的且比 它高的发射站接收. 显然,每个发射站发来的能量有可能被 0 或 1 或 2 个其他发射站所接受,特别是为了安 全,每个发射站接收到的能量总和是我们很关心的问题.由于数据很多,现只需要你帮忙计 算出接收

【单调队列】【cogs825】【RQNOJ 167】免费午餐

825. [RQNOJ 167] 免费午餐 ★☆ 输入文件:lunch.in 输出文件:lunch.out 简单对比 时间限制:1 s 内存限制:128 MB [问题描述] 为了增加顾客,Sally的店铺决定提供免费午餐,顿时门庭若市,但是不久Sally的原材料不足了-.因此Sally决定公布一项决定:凡是来本店吃免费午餐的,一天吃能吃一次,吃的数量必须比上一次吃的少,且免费午餐将只有N个种类任君选择,为了能吃到最多的免费午餐,你将如何安排每日吃的数量呢? [输入文件] 第一行一个数N,表示免费

Tyvj1305最大子序和(单调队列优化dp)

描述 输入一个长度为n的整数序列,从中找出一段不超过M的连续子序列,使得整个序列的和最大. 例如 1,-3,5,1,-2,3 当m=4时,S=5+1-2+3=7当m=2或m=3时,S=5+1=6 输入格式 第一行两个数n,m第二行有n个数,要求在n个数找到最大子序和 输出格式 一个数,数出他们的最大子序和 测试样例1 输入 6 4 1 -3 5 1 -2 3 输出 7 备注 数据范围:100%满足n,m<=300000 是不超过m,不是选m个!!!!! /* 单调队列优化dp 单调队列维护的是前

vijos P1243 生产产品(单调队列+DP)

P1243生产产品 描述 在经过一段时间的经营后,dd_engi的OI商店不满足于从别的供货商那里购买产 品放上货架,而要开始自己生产产品了!产品的生产需要M个步骤,每一个步骤都可以在N台机器中的任何一台完成,但生产的步骤必须严格按顺序执行.由于这N 台机器的性能不同,它们完成每一个步骤的所需时间也不同.机器i完成第j个步骤的时间为T[i,j].把半成品从一台机器上搬到另一台机器上也需要一定的 时间K.同时,为了保证安全和产品的质量,每台机器最多只能连续完成产品的L个步骤.也就是说,如果有一台机