P3512 [POI2010]PIL-Pilots
我一开始打的O(n^2)(最坏情况)的算法.枚举区间长度。60分
#include<iostream> #include<cstdio> #include<queue> #include<algorithm> #include<cmath> #include<ctime> #include<cstring> #define len 3000010 #define inf 2147483647 #define For(i,a,b) for(register int i=a;i<=b;i++) #define p(a) putchar(a) #define g() getchar() //by war //2017.10.9 using namespace std; int n,c; int a[len]; int qz[len]; int qj[len]; int lz,rz,lj,rj; void in(int &x) { char c=g();x=0; while(c<'0'||c>'9')c=g(); while(c<='9'&&c>='0')x=x*10+c-'0',c=g(); } void o(int x) { if(x>9)o(x/10); p(x%10+'0'); } int main() { in(c),in(n); For(i,1,n) in(a[i]); for(register int k=n;k>=1;k--) { lz=1,rz=0,lj=1,rj=0; For(i,1,n) { while(lj<=rj&&a[qj[rj]]<=a[i])rj--; qj[++rj]=i; while(qj[rj]-qj[lj]>=k)lj++; while(lz<=rz&&a[qz[rz]]>=a[i])rz--; qz[++rz]=i; while(qz[rz]-qz[lz]>=k)lz++; if(i>=k) { if(a[qj[lj]]-a[qz[lz]]<=c) { o(k); exit(0); } } } } return 0; }
正解不用枚举区间长度,动态维护+更新答案,O(n).
#include<iostream> #include<cstdio> #include<queue> #include<algorithm> #include<cmath> #include<ctime> #include<cstring> #define len 3000010 #define inf 2147483647 #define For(i,a,b) for(register int i=a;i<=b;i++) #define p(a) putchar(a) #define g() getchar() //by war //2017.10.9 using namespace std; int n,c; int a[len]; int qz[len]; int qj[len]; int lz,rz,lj,rj; int ans,last; void in(int &x) { char c=g();x=0; while(c<'0'||c>'9')c=g(); while(c<='9'&&c>='0')x=x*10+c-'0',c=g(); } void o(int x) { if(x>9)o(x/10); p(x%10+'0'); } int main() { in(c),in(n); For(i,1,n) in(a[i]); lz=1,rz=0,lj=1,rj=0; For(i,1,n) { while(lj<=rj&&a[qj[rj]]<=a[i])rj--; while(lz<=rz&&a[qz[rz]]>=a[i])rz--; qj[++rj]=i;qz[++rz]=i; while(a[qj[lj]]-a[qz[lz]]>c) if(qj[lj]<qz[lz]) last=qj[lj],lj++; else last=qz[lz],lz++; ans=max(ans,i-last); } o(ans); return 0; }