1. 程式人生 > >BZOJ 1637 [Usaco2007 Mar]Balanced Lineup:前綴和 + 差分

BZOJ 1637 [Usaco2007 Mar]Balanced Lineup:前綴和 + 差分

_id bzoj ret iostream 必須 namespace tor http int()

題目鏈接:http://www.lydsy.com/JudgeOnline/problem.php?id=1637

題意:

  Farmer John 決定給他的奶牛們照一張合影,他讓 N (1 ≤ N ≤ 50,000) 頭奶牛站成一條直線,每頭牛都有它的坐標x(0 <= x <= 10^9)和種族(0或1)。

  他只給一部分牛照相,並且這一組牛的陣容必須是“平衡的”。

  平衡的陣容,指的是在一組牛中,種族0和種族1的牛的數量相等。

  區間的大小為區間內最右邊的牛的坐標減去最做邊的牛的坐標。

  請算出最廣闊的區間,使這個區間內的牛陣容平衡。

題解:

  先將所有牛按坐標x從小到大排序。

  在id = 0處+1,在id = 1處-1。

  sum[i]為第i頭牛處的前綴和。

  結論:

    對於一段牛的0和1數量相等的區間[L,R](L,R為牛的編號),sum[R] = sum[L-1](因為相等數量的+1和-1抵消掉了)。

  所以對於每頭牛i,右端點為i的最大區間為[j+1,i],其中sum[j] = sum[i]。

  用pos數組記錄每一種sum值,最早出現的牛的右邊的牛的坐標x。

  然後掃一遍就好了。

AC Code:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <algorithm>
 5
#define MAX_N 100005 6 7 using namespace std; 8 9 struct Cow 10 { 11 int id; 12 int x; 13 Cow(int _id,int _x) 14 { 15 id=_id; 16 x=_x; 17 } 18 Cow(){} 19 friend bool operator < (const Cow &a,const Cow &b) 20 { 21 return a.x<b.x;
22 } 23 }; 24 25 int n; 26 int ans=0; 27 int pos[MAX_N]; 28 int sum[MAX_N]; 29 Cow c[MAX_N]; 30 31 void read() 32 { 33 cin>>n; 34 for(int i=1;i<=n;i++) 35 { 36 cin>>c[i].id>>c[i].x; 37 } 38 } 39 40 void solve() 41 { 42 sort(c+1,c+n+1); 43 memset(pos,-1,sizeof(pos)); 44 sum[0]=0; 45 for(int i=1;i<=n;i++) 46 { 47 sum[i]=sum[i-1]+(c[i].id==0?1:-1); 48 if(pos[sum[i]+n]==-1) pos[sum[i]+n]=c[i+1].x; 49 else ans=max(ans,c[i].x-pos[sum[i]+n]); 50 } 51 } 52 53 void print() 54 { 55 cout<<ans<<endl; 56 } 57 58 int main() 59 { 60 read(); 61 solve(); 62 print(); 63 }

BZOJ 1637 [Usaco2007 Mar]Balanced Lineup:前綴和 + 差分