*点击

[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

输入如下图所示


输出如下图所示

 


 

思路:

看上面的样例,我们会发现0-10坐标区间内1比0多2个,0-22区间内1比0也多2个;

我们也发现0-10坐标区间内1的个数为2个,0的个数为0个,0-22区间内1个数为4个,0的个数为2个;

这两个区间的0,1个数相减,可以得出11-22区间内0,1的个数,同时我们会发现0和1的个数都为2;

说明  0~x1,0~x2的0,1个数的差值相同,那么说明x1+1~x2的区间内0和1的个数相等;

看起来像是统计前缀,其实也是统计前缀,但用更快的方法不需要直接统计

我们可以先按坐标排序,然后把种族数字为0的改为-1;

从0~x种族数字相加,就可以统计出0~x之间0,1个数的差值;



我们就需要记下每个坐标的序号

如 1  4

    1  7

坐标4的序号是1,坐标7的序号是2;

那么求出差值相同的坐标0~x1,0~x2中x1,x2的序号y1,y2,再a[y2]-a[y1+1]求出区间长度,即可;

最后用max求出最大区间长度就可以了

 


 

代码:

 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read()
{
    ll a=0,f=1; char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
    return a*f;
}
struct sbbb
{
    ll x,y;
}a[500001];//结构体 x 代表每头牛的种族,y 是坐标 
ll n,ans,num,f[500001];
inline ll cmp(sbbb a,sbbb b)
{
    return a.y<b.y;
}//按坐标从小到大排序 
int main()
{
    n=read();
    for(ll i=1;i<=n;i++)
    {
        a[i].x=read();
        a[i].y=read();
        if(a[i].x==0)
            a[i].x=-1;//将每个种族为0的牛,把种族改为-1,方便统计 
    }
    sort(a+1,a+n+1,cmp);//排序 
    for(ll i=1;i<=n;i++)
    {
        num+=a[i].x;//计算差值 
        if(!f[num+n])//记下第一次出现的差值 因为差值可能是负数,所以下标加上n 
            f[num+n]=i;//记下坐标的序号 
        else
            ans=max(ans,a[i].y-a[f[num+n]+1].y);//统计最大区间长度 
    }
    printf("%lld",ans);
}

 

 

 

posted @ 2020-06-05 22:26  木偶人-怪咖  阅读(299)  评论(0编辑  收藏  举报
*访客位置3D地图 *目录