题意:FJ 决定将一些奶牛(也许全部)摄入其家庭画像中,为方便取像, FJ 已安排所有 FJ 总是做一些别出心裁的事情,当然这项活动也不例外。他决定在他的照片中将只有一部分奶牛,并且照片必须在“平衡” 。所谓“平衡”,就是指连续的一组奶牛中,包含的两种品种数量是一样的,即 FJ 确定相片的最大宽度。注意,在
这道题要转个弯,然后就很简单。
首先一想到就是 DP,我们用
怎么求这个差值呢?我们只需把
但是怎么求一个子串内的
| 坐标 | |||||||
|---|---|---|---|---|---|---|---|
| 类型 | |||||||
很容易可以发现,当这个子串为
证明也很简单,由于
于是我们用一个 vector 数组,把每个
最后注意如果最大下标和最小下标相同,说明只是一个数,需要特判。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=200000;
int n,sum[201010],minn=1e9,maxx=-1e9,ans=-1e9;
struct node
{
int p;
int d;
}a[201010];
vector<int> s[401010];
int cmp(node x,node y)
{
return x.d<y.d;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i].p,&a[i].d);
if(!a[i].p)
a[i].p=-1;
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)
{
sum[i]=sum[i-1]+a[i].p;
s[sum[i]+maxn].push_back(i);
minn=min(minn,sum[i]);
maxx=max(maxx,sum[i]);
}
for(int i=minn;i<=maxx;i++)
{
int maxd=-1e9;
int mind=1e9;
for(int j=0;j<s[i+maxn].size();j++)
{
maxd=max(maxd,s[i+maxn][j]);
mind=min(mind,s[i+maxn][j]);
}
if(maxd==mind)
mind=maxd-1;
ans=max(ans,a[maxd].d-a[mind+1].d);
}
printf("%d",ans);
return 0;
}