9
13
2015
0

2096: [Poi2010]Pilots

2096: [Poi2010]Pilots

Time Limit: 30 Sec  Memory Limit: 162 MB
Submit: 438  Solved: 219
[Submit][Status][Discuss]

Description

Tz又耍畸形了!!他要当飞行员,他拿到了一个飞行员测试难度序列,他设定了一个难度差的最大值,在序列中他想找到一个最长的子串,任意两个难度差不会超过他设定的最大值。耍畸形一个人是不行的,于是他找到了你。

Input

输入:第一行两个有空格隔开的整数k(0<=k<=2000,000,000),n(1<=n<=3000,000),k代表Tz设定的最大值,n代表难度序列的长度。第二行为n个由空格隔开的整数ai(1<=ai<=2000,000,000),表示难度序列。

Output

输出:最大的字串长度。

Sample Input

3 9
5 1 3 5 8 6 6 9 10

Sample Output

4
(有两个子串的长度为4: 5, 8, 6, 6 和8, 6, 6, 9.最长子串的长度就是4)

HINT

 

Source

    这道题有两种做法。。可以二分长度然后单调队列验证。。也可以用堆做。。

    堆:

    从头到尾枚举每一个元素,将其分别加入大根堆和小根堆中。。然后维护一个右边界表示没有冲突的最右边的位置。。如果发现有冲突了,就调整右边界的位置,然后将堆中不在范围里的元素弹出。

#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 3000010;
struct data{int val,id;};
int a[N],n,K,ans;
bool operator < (data a,data b){return a.val<b.val;}
int read(){
	int x = 0,f = 1,c = getchar();
	while (c<'0' || c>'9'){if (c=='-') f = -1;c = getchar();}
	while (c>='0' && c<='9') x = x*10+c-'0',c = getchar();
	return x*f;
}
priority_queue<data> q1,q2;
void solve(){
	int l = 1;
	for (int i=1;i<=n;i++){
		q1.push((data){a[i],i});
		q2.push((data){-a[i],i});
		while (q1.top().val+q2.top().val>K){
			l++;
			while (!q1.empty() && q1.top().id<l) q1.pop();
			while (!q2.empty() && q2.top().id<l) q2.pop();
		}
		ans = max(ans,i-l+1);
	}
}
int main(){
	K = read();n = read();
	for (int i=1;i<=n;i++) a[i] = read();
	solve();
	printf("%d",ans);
}
Category: BZOJ题解 | Tags: | Read Count: 369

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com