Subsequence
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 9847 Accepted Submission(s): 3292
Problem Description
There is a sequence of integers. Your task is to find the longest subsequence that satisfies the following condition: the difference between the maximum element and the minimum element of the subsequence is no smaller than m and no larger than k.
Input
There are multiple test cases.
For each test case, the first line has three integers, n, m and k. n is the length of the sequence and is in the range [1, 100000]. m and k are in the range [0, 1000000]. The second line has n integers, which are all in the range [0, 1000000].
Proceed to the end of file.
For each test case, the first line has three integers, n, m and k. n is the length of the sequence and is in the range [1, 100000]. m and k are in the range [0, 1000000]. The second line has n integers, which are all in the range [0, 1000000].
Proceed to the end of file.
Output
For each test case, print the length of the subsequence on a single line.
Sample Input
5 0 0
1 1 1 1 1
5 0 3
1 2 3 4 5
Sample Output
5
4
题意:给出一个长度为n的数列,求一个最长的区间,使得区间中最小值和最大值的差在[m,k]之间 (来自vj)
思路:
维护两个单调队列,这里的单调队列并不是维护一个固定滑动窗口的值,而是有自己的出队规则。
两个单调队列,一个非增,一个非降。
按输入顺序开始更新两个单调队列,倘若当前的值会更新最小值,并且与目前单调队列的最大值的差大于k,那么就要舍弃这个最大值。显而易见,这个最大值之前的位置也一定不会是要求区间的左端点。
倘若当前的值会更新最大值,同理。
但是在代码中,并没有判断当前更新的是最大还是最小值。因为如果你更新的是最小值,维护最小值的单调队列首部位置就是当前位置,而维护最大值的单调队列首部位置一定小于等于当前位置,如果更新的是最大值同理。所以只需要去掉那个靠前的就行了。
用一个pre维护最后一个去掉的位置,这个位置的后一个位置就可能是要求区间的左端点。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<algorithm> 3 #include<vector> 4 #include<stack> 5 #include<queue> 6 #include<map> 7 #include<set> 8 #include<cstdio> 9 #include<cstring> 10 #include<cmath> 11 #include<ctime> 12 #define fuck(x) cout<<#x<<" = "<<x<<endl; 13 #define debug(a,i) cout<<#a<<"["<<i<<"] = "<<a[i]<<endl; 14 #define ls (t<<1) 15 #define rs ((t<<1)+1) 16 using namespace std; 17 typedef long long ll; 18 typedef unsigned long long ull; 19 const int maxn = 100086; 20 const int maxm = 100086; 21 const int inf = 2.1e9; 22 const ll Inf = 999999999999999999; 23 const int mod = 1000000007; 24 const double eps = 1e-6; 25 const double pi = acos(-1); 26 27 struct node{ 28 int num,pos; 29 }; 30 int num[maxn]; 31 deque<node>q1,q2; 32 33 int main() 34 { 35 // ios::sync_with_stdio(false); 36 // freopen("in.txt","r",stdin); 37 38 int n,m,k; 39 while(scanf("%d%d%d",&n,&m,&k)!=EOF){ 40 for(int i=1;i<=n;i++){ 41 scanf("%d",&num[i]); 42 } 43 int ans=0;int pre=0; 44 q1.clear(); 45 q2.clear(); 46 for(int i=1;i<=n;i++){ 47 while(!q1.empty()&&q1.back().num<num[i]){ 48 q1.pop_back(); 49 }while(!q2.empty()&&q2.back().num>num[i]){ 50 q2.pop_back(); 51 } 52 q1.push_back(node{num[i],i}); 53 q2.push_back(node{num[i],i}); 54 while(q1.front().num-q2.front().num>k){ 55 if(q1.front().pos<q2.front().pos){ 56 pre=q1.front().pos; 57 q1.pop_front(); 58 } 59 else{ 60 pre=q2.front().pos; 61 q2.pop_front(); 62 } 63 } 64 if(q1.front().num-q2.front().num>=m){ 65 ans=max(ans,i-pre); 66 } 67 } 68 printf("%d ",ans); 69 } 70 71 72 return 0; 73 }