1. 程式人生 > >Subsequence HDU - 3530

Subsequence HDU - 3530

sin 最小 mes pri blank 記錄 while point targe

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 }

Subsequence HDU - 3530