Subsequence HDU - 3530

Subsequence HDU - 3530

方法:单调队列区间最大最小

错误记录(本地写错)的原因:写成每次试着扩展右端点,却难以正确地处理"在多扩展右端点之后减去多扩展的部分"这一任务(分类太多,例如:由于无法扩展有端点有可能是因为有端点已经到达最右端,也可能是因为最大最小差超过要求)。显然那样写没有每次扩展一个右端点,并从左侧开始删直到重新使序列符合标准(two_pointers?)方便。

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 int a[100100],qmin[101000],qmax[101000],n,m,k,lmin,rmin,lmax,rmax,l,r,maxans;
 5 int main()
 6 {
 7     int i;
 8     while(scanf("%d%d%d",&n,&m,&k)==3)
 9     {
10         lmin=rmin=lmax=rmax=maxans=0;l=1;
11         for(i=1;i<=n;i++)
12             scanf("%d",&a[i]);
13         for(r=1;r<=n;r++)
14         {
15             while(lmin<rmin&&a[qmin[rmin-1]]>=a[r])    --rmin;
16             qmin[rmin++]=r;
17             while(lmax<rmax&&a[qmax[rmax-1]]<=a[r])    --rmax;
18             qmax[rmax++]=r;
19             while(l<=r&&(a[qmax[lmax]]-a[qmin[lmin]]>k))
20             {
21                 if(lmin<rmin&&qmin[lmin]<=l)    lmin++;
22                 if(lmax<rmax&&qmax[lmax]<=l)    lmax++;
23                 l++;
24             }
25             if(l<=r&&a[qmax[lmax]]-a[qmin[lmin]]>=m)
26                 maxans=max(maxans,r-l+1);
27         }
28         printf("%d\n",maxans);
29     }
30     return 0;
31 }
posted @ 2017-10-27 20:07  hehe_54321  阅读(143)  评论(0编辑  收藏  举报
AmazingCounters.com