[BZOJ1637][Usaco2007 Mar]Balanced Lineup

Description

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

Input

行 1: 一个整数: N 行 2..N + 1: 每行两个整数,为种族 ID 和 x 坐标。

Output

行 1: 一个整数,阵容平衡的最大的区间的大小。

Sample Input

7
0 11
1 10
1 25
1 12
1 4
0 13
1 22

Sample Output

11

HINT

输入说明 


有7头牛,像这样在数轴上。 



输出说明 


牛 #1 (at 11), #4 (at 12), #6 (at 13), #7 (at 22) 组成一个平衡的最大的区间,大小为 22-11=11 个单位长度。 

 

Source

Silver

 


 

 

第一眼看woc这是裸的前缀和,又一想,诶,貌似前缀和是n^2的...

然后我的思路就成功地走上了不归路...

最后..woc这么简单???

我们把typ是0的全部当做-1, 然后我们再做前缀和, 这样如果得到了两个位置的前缀和相等, 那么这一个区间一定是平衡的。

所以我们记录一下每一个sum值的最早出现位置,然后每次扫到这个值,就更新一下答案。

注意sum初值要设成5000,防止故意出数据爆负数,vis数组开大一倍...

还有...我再也不写重载运算符了...Linux下不停CE

 


 

 

 

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll ;
#define gc getchar
inline ll read(){
    ll res=0;char ch=gc();
    while(!isdigit(ch))ch=gc();
    while(isdigit(ch)){res=(res<<3)+(res<<1)+(ch^48);ch=gc();}
    return res;
}
int n;
struct date{
    int typ, x;
}d[50005];
int vis[100005];
int sum[50005];
ll ans;

inline bool cmp(date a, date b){return a.x < b.x;}

int main()
{
    n = read();
    for (int i = 1 ; i <= n ; i ++)
        d[i].typ = (read()==1) ? 1 : -1, d[i].x = read();
    sort(d+1,d+1+n, cmp);
    memset(vis, -1, sizeof vis);
    sum[0] = 50000;
    for (int i = 1 ; i <= n ; i ++)
    {
        sum[i] = sum[i-1] + d[i].typ;
        if (vis[sum[i]] == -1) vis[sum[i]] = i + 1;
        else ans = max(ans, (ll)(d[i].x - d[vis[sum[i]]].x));
    }
    cout<<ans<<endl;
    return 0;
}

 

 

 

posted @ 2018-07-23 22:53  zZhBr  阅读(111)  评论(0编辑  收藏  举报