洛谷 3029 [USACO11NOV]牛的阵容Cow Lineup
【题解】
单调队列或者Two Pointers.
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define LL long long 5 #define rg register 6 #define N 200010 7 using namespace std; 8 int n,m,cnt,front=1,rear,ans=2e9,b[N],q[N],v[N]; 9 struct poi{int x,d;}a[N]; 10 inline int read(){ 11 int k=0,f=1; char c=getchar(); 12 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 13 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 14 return k*f; 15 } 16 inline bool cmp(poi a,poi b){return a.x<b.x;} 17 int main(){ 18 n=read(); 19 for(rg int i=1;i<=n;i++) a[i].x=read(),a[i].d=b[i]=read(); 20 sort(a+1,a+1+n,cmp); sort(b+1,b+1+n); m=unique(b+1,b+1+n)-b-1; 21 for(rg int i=1;i<=n;i++) a[i].d=lower_bound(b+1,b+1+m,a[i].d)-b; 22 // for(rg int i=1;i<=n;i++) printf("%d %d\n",a[i].x,a[i].d); puts(""); 23 for(rg int i=1;i<=n;i++){ 24 if(!v[a[i].d]) cnt++; 25 v[a[i].d]++; q[i]=i; 26 while(front<i&&v[a[q[front]].d]>1) v[a[q[front++]].d]--; 27 if(cnt>=m) ans=min(ans,a[i].x-a[q[front]].x); 28 // printf("f=%d r=%d cnt=%d\n",front,i,cnt); 29 } 30 printf("%d\n",ans); 31 return 0; 32 }