BZOJ2096: [Poi2010]Pilots
2096: [Poi2010]Pilots
Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 914 Solved: 467
[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
5 1 3 5 8 6 6 9 10
Sample Output
4
(有两个子串的长度为4: 5, 8, 6, 6 和8, 6, 6, 9.最长子串的长度就是4)
(有两个子串的长度为4: 5, 8, 6, 6 和8, 6, 6, 9.最长子串的长度就是4)
HINT
Source
【题解】
单调队列 + 尺取法裸题
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #define max(a, b) ((a) > (b) ? (a) : (b)) 6 7 inline void read(long long &x) 8 { 9 char ch = getchar(), c = ch;x = 0; 10 while(ch < '0' || ch > '9')c = ch, ch = getchar(); 11 while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar(); 12 if(c == '-')x = -x; 13 } 14 15 const int INF = 0x3f3f3f3f; 16 const int MAXN = 3000000 + 10; 17 18 long long k,l,n,num,ans,q1[MAXN],q2[MAXN],rank1[MAXN],rank2[MAXN],head1,tail1,head2,tail2; 19 20 int main() 21 { 22 read(k), read(n); 23 ans = 1; 24 read(num); 25 head1 = tail1 = head2 = tail2 = l = 1, q1[1] = q2[1] = num; 26 rank1[1] = rank2[1] = 1; 27 //q1单调递减 28 //q2单调递增 29 for(register int i = 2;i <= n;++ i) 30 { 31 read(num); 32 while(num >= q1[tail1] && tail1 >= head1)-- tail1; 33 q1[++tail1] = num; 34 rank1[tail1] = i; 35 while(num <= q2[tail2] && tail2 >= head2)-- tail2; 36 q2[++tail2] = num; 37 rank2[tail2] = i; 38 while(q1[head1] - q2[head2] > k && head1 <= tail1 && head2 <= tail2) 39 { 40 ++ l; 41 while(rank1[head1] < l && head1 <= tail1)++ head1; 42 while(rank2[head2] < l && head2 <= tail2)++ head2; 43 } 44 ans = max(ans, i - l + 1); 45 } 46 printf("%d", ans); 47 return 0; 48 }