CSU 1553 Good subsequence(RMQ问题 + 二分)
题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1553
Description
Give you a sequence of n numbers, and a number k you should find the max length of Good subsequence. Good subsequence is a continuous subsequence of the given sequence and its maximum value - minimum value<=k. For example n=5, k=2, the sequence ={5, 4, 2, 3, 1}. The answer is 3, the good subsequence are {4, 2, 3} or {2, 3, 1}.
Input
There are several test cases.
Each test case contains two line. the first line are two numbers indicates n and k (1<=n<=10,000, 1<=k<=1,000,000,000). The second line give the sequence of n numbers a[i] (1<=i<=n, 1<=a[i]<=1,000,000,000).
The input will finish with the end of file.
Output
For each the case, output one integer indicates the answer.
Sample Input
5 2 5 4 2 3 1 1 1 1
Sample Output
3 1
Hint
Source
题意:
给你一个n个数,在这些数里面找一段连续区间,这个区间需要满足这个区间里的最大值-最小值 <= k。找出最大的区间长度。
题解:
拿到题的时候,就想到RMQ来找区间最值,二分长度找最大值。
然后队伍分工合作,一个人写二分,我写RMQ。一不小心写错了一个点wa了一次,QAQ。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <string> 6 #include <vector> 7 #include <map> 8 #include <set> 9 #include <queue> 10 #include <sstream> 11 #include <algorithm> 12 using namespace std; 13 #define pb push_back 14 #define mp make_pair 15 #define ms(a, b) memset((a), (b), sizeof(a)) 16 //#define LOCAL 17 #define eps 0.0000001 18 #define LNF (1<<60) 19 typedef long long LL; 20 const int inf = 0x3f3f3f3f; 21 const int maxn = 10000+10; 22 const int mod = 1e9+7; 23 24 LL st_max[16][maxn], st_min[16][maxn]; 25 LL A[maxn]; 26 void RMQ_init(int n){ 27 for(int i=0;i<n;i++) st_max[0][i]=st_min[0][i]= A[i]; 28 for(int j = 1;(1<<j) <= n;j++){ 29 int k = 1<<(j-1); 30 for(int i=0;i+k<n;i++){ 31 st_max[j][i] = max(st_max[j-1][i], st_max[j-1][i+k]); 32 st_min[j][i] = min(st_min[j-1][i], st_min[j-1][i+k]); 33 } 34 } 35 } 36 LL RMQ(int a, int b){ 37 int dis = abs(b-a) + 1; 38 int k; 39 for(k=0;(1<<k)<=dis;k++); 40 k--; 41 // printf("%lld %lld\n", max(st_max[k][a], st_max[k][b-(1<<k)+1]), min(st_min[k][a], st_min[k][b-(1<<k)+1])); 42 return max(st_max[k][a], st_max[k][b-(1<<k)+1])-min(st_min[k][a], st_min[k][b-(1<<k)+1]); 43 } 44 int test(int len, int n, int k) 45 { 46 for(int i = len-1; i<n; i++){ 47 if(RMQ(i-len+1, i)<=1LL*k) 48 return 1; 49 } 50 return 0; 51 } 52 int main() 53 { 54 #ifdef LOCAL 55 freopen("input.txt", "r", stdin); 56 // freopen("output.txt", "w", stdout); 57 #endif // LOCAL 58 59 int n, k; 60 while(~scanf("%d%d", &n, &k)){ 61 ms(st_max, 0); 62 ms(st_min, 0); 63 ms(A, 0); 64 for(int i=0;i<n;i++) scanf("%lld", &A[i]); 65 RMQ_init(n); 66 // printf("%lld\n", RMQ(0, n-1)); 67 int l = 0, r = n+1; 68 int mid, ans; 69 while(l<r){ 70 mid = (l+r)/2; 71 if(test(mid, n, k)){ 72 ans = mid; 73 l = mid+1; 74 } 75 else 76 r = mid; 77 } 78 printf("%d\n", ans); 79 } 80 return 0; 81 }
模板题。XD