题意是说给出一个序列,现在要求出这个序列的一个最长子区间,要求子区间的最大值与最小值的差在[m, k]范围内,求区间长度

做法是维护两个队列,一个维护到当前位置的最大值,一个维护最小值,然后计算当前节点i作为右端点的最常区间长度,那么扫描两个队列,维持单调性。

然后比较两个队列头的差值,

1.如果差值满足条件,那么记录答案;

2.如果差值小于m,那么此时没有答案,说明没有以i作为右端点的区间满足条件(表示前i个数的最大值减去前i个数的最小值的差<m,那么不论如何调整起点,都不可能有解)

3.如果差值大于k,说明此时区间的最大值与最小值的差过大,那我们可以通过缩小最大值(最大值(递减)队列向右移动)或者增大最小值(最小值(递增)队列向右移动)的方法使得差值变小,那到底是移动哪一个指针取决于此时队首的这两个值谁的编号要小(保证区间是合法的)。

另外有一点要注意的细节是,上述的第三种情况,在移动队首的指针时,如果最后被删除的元素所指向的下标p,此时队首的元素指向的下标是q, 此时合法区间为[p +1, i]而不是[q, i]

 //#pragma comment(linker, "/STACK:1677721600")
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define inf (-((LL)1<<40))
#define lson k<<1, L, (L + R)>>1
#define rson k<<1|1, ((L + R)>>1) + 1, R
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
#define FIN freopen("in.txt", "r", stdin)
#define FOUT freopen("out.txt", "w", stdout)
#define rep(i, a, b) for(int i = a; i <= b; i ++)
#define dec(i, a, b) for(int i = a; i >= b; i --) template<class T> T MAX(T a, T b) { return a > b ? a : b; }
template<class T> T MIN(T a, T b) { return a < b ? a : b; }
template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b; } //typedef __int64 LL;
typedef long long LL;
const int MAXN = + ;
const int MAXM = ;
const double eps = 1e-;
LL MOD = ; int a[MAXN], L, H, n;
int q1[MAXN], q2[MAXN]; int find_ans() {
int f1, f2, t1, t2, l1 = -, l2 = -, ans = ;
f1 = f2 = t1 = t2 = ;
rep (i, , n - ) {
while(f1 < t1 && a[q1[t1 - ]] <= a[i]) t1 --;//维护最大值队列(递减)
q1[t1++] = i;
while(f2 < t2 && a[q2[t2 - ]] >= a[i]) t2 --;//维护最小值队列(递增)
q2[t2++] = i;
while(a[q1[f1]] - a[q2[f2]] > H) {//差值过大
q1[f1] < q2[f2] ? l1 = q1[f1 ++] : l2 = q2[f2 ++];
}
if(a[q1[f1]] - a[q2[f2]] >= L) {//差值满足条件
ans = max(ans, i - max(l1, l2));
}
}
return ans;
} int main()
{
while(~scanf("%d %d %d", &n, &L, &H)) {
rep (i, , n - ) scanf("%d", a + i);
printf("%d\n", find_ans());
}
return ;
}

HDU3530 Subsequence(单调队列)的更多相关文章

  1. HDU - 3530 Subsequence (单调队列)

    Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  2. hdu3530 双单调队列的维护

    单调队列有部分堆的功能,但其只能维护给定区间中比v大的值或者比v小的值,且其一般存储元素的下标. 思路:两个单调队列维护最大值与最小值的下标,如果区间的最大值最小值之差大于给定范围,则选择队首靠左的删 ...

  3. hdu 3530 Subsequence 单调队列

    题目链接 题目给出n个数, 一个下界m, 一个上界k, 让你求出最长的一段序列, 满足这段序列中的最大的数-最小的数<=k&&>=m, 输出这段长度. 可以维护两个队列, ...

  4. [hdu3530]Subsequence (单调队列)

    题意:求在一段序列中满足m<=max-min<=k的最大长度. 解题关键:单调队列+dp,维护前缀序列的最大最小值,一旦大于k,则移动左端点,取max即可. #include<cst ...

  5. Subsequence(HDU3530+单调队列)

    题目链接 传送门 题面 题意 找到最长的一个区间,使得这个区间内的最大值减最小值在\([m,k]\)中. 思路 我们用两个单调队列分别维护最大值和最小值,我们记作\(q1\)和\(q2\). 如果\( ...

  6. hdu3530 单调队列

    Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tota ...

  7. HDU 3530 Subsequence(单调队列)

    传送门 Description There is a sequence of integers. Your task is to find the longest subsequence that s ...

  8. Subsequence(两个单调队列)

    Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tota ...

  9. 【单调队列+尺取】HDU 3530 Subsequence

    acm.hdu.edu.cn/showproblem.php?pid=3530 [题意] 给定一个长度为n的序列,问这个序列满足最大值和最小值的差在[m,k]的范围内的最长子区间是多长? [思路] 对 ...

  10. 【专题系列】单调队列优化DP

    Tip:还有很多更有深度的题目,这里不再给出,只给了几道基本的题目(本来想继续更的,但是现在做的题目不是这一块内容,以后有空可能会继续补上) 单调队列——看起来就是很高级的玩意儿,显然是个队列,而且其 ...

随机推荐

  1. Linux proc 内存

    ps: USER      PID    %CPU %MEM   VSZ   RSS  TTY  STAT  START  TIME  COMMAND root          4238     0 ...

  2. Flask 使用富文本输入框

    模板 <script src="{{ url_for('static', filename='ckeditor/ckeditor.js') }}"></scrip ...

  3. Java实现动态规划法求解0/1背包问题

    摘要: 使用动态规划法求解0/1背包问题. 难度: 初级 0/1背包问题的动态规划法求解,前人之述备矣,这里所做的工作,不过是自己根据理解实现了一遍,主要目的还是锻炼思维和编程能力,同时,也是为了增进 ...

  4. TED #02#

    Amanda Palmer: The art of asking 1. I think people have been obsessed with the wrong question, which ...

  5. 获取lambda表达式类型,获取attributes是注意事项

    1.获取lambda表达式的MemberExpression所属类的类型,要使用:m.Expression.Type   而不要使用 m.Member.DeclaringType: 后者获取的是实际定 ...

  6. SpringBoot与Dubbo整合下篇

    (1)pom.xml引入相关依赖jar包,如下: <dependency> <groupId>com.alibaba</groupId> <artifactI ...

  7. Maximum Depth of Binary Tree,求树的最大深度

    算法分析:求树的最小最大深度时候,都有两种方法,第一种是递归思想.树最大最小深度,即为它的子树的最大最小深度+1,是动态规划的思想.还有一种方法是层序遍历树,只不过求最小深度时,找到第一个叶子节点就可 ...

  8. MySQL 5.7.17 Windows安装和启动

    1.在官网http://dev.mysql.com/downloads/下载 MySQL Community Server 2.解压后是这个样子(5.7.18解压后没有my-default.ini文件 ...

  9. Codeforces Round #169 (Div. 2) E. Little Girl and Problem on Trees dfs序+线段树

    E. Little Girl and Problem on Trees time limit per test 2 seconds memory limit per test 256 megabyte ...

  10. poj 2828 Buy Tickets 树状数组

    Buy Tickets Description Railway tickets were difficult to buy around the Lunar New Year in China, so ...