【BZOJ2096】[Poi2010]Pilots 雙指針+單調隊列
阿新 • • 發佈:2017-08-26
printf rip const urn esc 最小值 == () script
3 9
5 1 3 5 8 6 6 9 10
(有兩個子串的長度為4: 5, 8, 6, 6 和8, 6, 6, 9.最長子串的長度就是4)
【BZOJ2096】[Poi2010]Pilots
Description
Tz又耍畸形了!!他要當飛行員,他拿到了一個飛行員測試難度序列,他設定了一個難度差的最大值,在序列中他想找到一個最長的子串,任意兩個難度差不會超過他設定的最大值。耍畸形一個人是不行的,於是他找到了你。
Input
輸入:第一行兩個有空格隔開的整數k(0<=k<=2000,000,000),n(1<=n<=3000,000),k代表Tz設定的最大值,n代表難度序列的長度。第二行為n個由空格隔開的整數ai(1<=ai<=2000,000,000),表示難度序列。
Output
輸出:最大的字串長度。
Sample Input
5 1 3 5 8 6 6 9 10
Sample Output
4(有兩個子串的長度為4: 5, 8, 6, 6 和8, 6, 6, 9.最長子串的長度就是4)
題解:雙指針+單調隊列維護最大最小值即可。
#include <cstdio> #include <cstring> #include <iostream> using namespace std; int n,k,h1,t1,h2,t2,ans; const int maxn=3000010; int q1[maxn],q2[maxn],v[maxn]; inline int rd() { int ret=0,f=1; char gc=getchar(); while(gc<‘0‘||gc>‘9‘) {if(gc==‘-‘)f=-f; gc=getchar();} while(gc>=‘0‘&&gc<=‘9‘) ret=ret*10+gc-‘0‘,gc=getchar(); return ret*f; } int main() { k=rd(),n=rd(); int i,j; for(i=1;i<=n;i++) v[i]=rd(); for(h1=h2=i=j=1;i<=n;i++) { while(h1<=t1&&v[q1[t1]]<=v[i]) t1--; q1[++t1]=i; while(h2<=t2&&v[q2[t2]]>=v[i]) t2--; q2[++t2]=i; while(v[q1[h1]]-v[q2[h2]]>k&&j<=i) { j++; while(h1<=t1&&q1[h1]<j) h1++; while(h2<=t2&&q2[h2]<j) h2++; } ans=max(ans,i-j+1); } printf("%d",ans); return 0; }
【BZOJ2096】[Poi2010]Pilots 雙指針+單調隊列