您的位置:首页 > 其它

BZOJ 2096

2016-07-06 20:21 127 查看
BZOJ 2096

【分析】

这道题就TM是个坑

给一段序列,求一段最长子序列,使序列中最大值-最小值<=k

分别用两个递增和递减的队列维护。枚举右端点,根据条件不断删除左端点,然后取min。

fffff**k

【代码】

#include<iostream>
#include<cstdio>
#include<algorithm>
#define fo(i,j,k) for(i=j;i<=k;i++)
using namespace std;
const int T=3000005;
int n,k,l1,r1,l2,r2,ans,t=1,a[T],q1[T],q2[T];
int main()
{
int i;
scanf("%d%d",&k,&n);
fo(i,1,n) scanf("%d", &a[i]);
fo(i,1,n)
{
while(l1<r1 && a[i]<=a[q1[r1-1]]) r1--;
while(l2<r2 && a[i]>=a[q2[r2-1]]) r2--;
q1[r1++]=q2[r2++] = i;
while(a[q2[l2]]-a[q1[l1]]>k)
if(q2[l2]>q1[l1]) t=q1[l1]+1,l1++;
else t=q2[l2]+1,l2++;
ans=max(ans,i-t+1);
}
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  单调队列