Subsequence
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3725 Accepted Submission(s): 1212
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
Source
Recommend
zhengfeng
也是一道单调队列水题,这次想着用结构化,结果又写了一晚上......
算法是维护两个单调队列,一个单增,一个单剪
两个队列首元素之差大于k就把某个队列(你懂得,首元素靠前的那一个)队首元素弹出
如果之差大于m小于k就是答案啦
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
const int N = 1000100;
using namespace std;
int d[N];
struct node
{
int q[N],p1,p2;
bool comp;
void init(bool x)
{
comp=x;
p2=0;
p1=1;
}
bool cmp(int x)
{
if(p1>p2)
return false;
if(comp)
return d[q[p2]]<x;
return d[q[p2]]>x;
}
void insert(int x)
{
q[++p2]=x;
}
bool empty()
{
return p1>p2;
}
int top()
{
return d[q[p1]];
}
int at()
{
return q[p1];
}
void pop()
{
// if(comp)printf("Up ");
// else printf("Down ");
// printf("Pop : %d\n",d[q[p2]]);
p2--;
}
void check()
{
if(comp)printf("Up ");
else printf("Down ");
for(int i=p1;i<=p2;i++)
printf("%d ",d[q[i]]);
putchar('\n');
}
}up,down;
bool solve()
{
int n,m,k,start=0,Ans=0;
if(scanf("%d %d %d",&n,&m,&k)==EOF)return false;
for(int i=1;i<=n;i++)
scanf("%d",&d[i]);
up.init(true);
down.init(false);
for(int i=1;i<=n;i++)
{
//printf("Working: %d of [%d]\n",d[i],i);
while(!up.empty() && up.cmp(d[i]))up.pop();
while(!down.empty() && down.cmp(d[i]))down.pop();
up.insert(i);
down.insert(i);
//printf("%d %d %d\n",up.top(),down.top(),up.top()-down.top());
while(!up.empty() && !down.empty() && up.top()-down.top()>k)
{
//printf("*** Too large.");
if(up.at()<down.at())
{
start=up.at();
up.p1++;
}
else
{
start=down.at();
down.p1++;
}
}
//printf("%d and %d cut : %d LEN %d\n",up.at(),down.at(),up.top()-down.top(),i-start);
// up.check();
// down.check();
if(up.top()-down.top()>=m)
Ans=max(Ans,i-start);
}
printf("%d\n",Ans);
return true;
}
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
while(solve());
return 0;
}