【差分+前缀和】BZOJ1637: [Usaco2007 Mar]Balanced Lineup

Description

Farmer John 决定给他的奶牛们照一张合影,他让 N (1 ≤ N ≤ 50,000) 头奶牛站成一条直线,每头牛都有它的坐标(范围: 0..1,000,000,000)和种族(0或1)。 一直以来 Farmer John 总是喜欢做一些非凡的事,当然这次照相也不例外。他只给一部分牛照相,并且这一组牛的阵容必须是“平衡的”。平衡的阵容,指的是在一组牛中,种族0和种族1的牛的数量相等。 请算出最广阔的区间,使这个区间内的牛阵容平衡。区间的大小为区间内最右边的牛的坐标减去最做边的牛的坐标。 输入中,每个种族至少有一头牛,没有两头牛的坐标相同。

 

Solution

设s[i]为前i头牛为1的牛数-为0的牛数

显然对于合法区间(l,r],s[l]==s[r]

扫一遍对于每个s统计下最左和最右就行了

秒之

 

Code

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 const int maxn=1e5+5;
 5 
 6 struct cow{
 7     int dfn,dis;
 8     bool operator<(const cow&b)
 9         const{return dis<b.dis;}
10 }a[maxn];
11 int s[maxn],l[maxn],r[maxn];
12 int n;
13 
14 int main(){
15     scanf("%d",&n);
16     for(int i=1;i<=n;i++)
17         scanf("%d%d",&a[i].dfn,&a[i].dis);
18     sort(a+1,a+n+1);
19     
20     for(int i=1;i<=n;i++){
21         if(a[i].dfn) s[i]=s[i-1]+1;
22         else s[i]=s[i-1]-1;
23         int x=s[i]+n;
24         if(!l[x]) l[x]=i;
25         else r[x]=i;
26     }
27     
28     int ans=0;
29     for(int i=0;i<=2*n;i++)
30         if(l[i]&&r[i]) ans=max(ans,a[r[i]].dis-a[l[i]+1].dis);
31     printf("%d\n",ans);
32     return 0;
33 }

 

posted @ 2015-06-09 01:45  CyanNode  阅读(786)  评论(0编辑  收藏  举报