题意解析
左边是数值,右边是布尔值,每次我们要选一个数值x,计算一下大于等于x的数值的且布尔值为1的个数,小于x的数值的且布尔值为0的个数,求一下累加和的最大值。
例如,我们选择3这个数值,那么大于等于它的数值且布尔值为1的个数有3个,小于它的数值且布尔值为0的个数有2个。一共有5个满足的数:
假设我们选取5这个数值,那么满足条件的有4个:
当我们选取第三个1的时候,满足条件的有5个:
已经可以确定最大满足条件的个数就是5,然后因为数值3的满足条件的个数也是5,且数值3比数值1的字典序大,所以输出3。
那么现在问题就转化为了我们每枚举一个数,就求一下这个数前面有多少个0,后面有多少个1:
这实际上就是求区间内元素个数,我们可以通过前缀和来求。
我们预处理一个s数组,si0表示i前面有多少个0,si1表示i前面有多少个1。
现在我们求i前面有多少个0就直接用s[0][i-1]求。我们想求i后面有多少个1就用s[1][n]-s[1][i-1]。
code
#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
const int N=1e5+10;
typedef pair<int,int>PII;
PII q[N];
int s[2][N];
int main()
{
int n;cin>>n;
for(int i=1;i<=n;i++)cin>>q[i].x>>q[i].y;
sort(q+1,q+n+1);
for(int i=0;i<2;i++)
{
for(int j=1;j<=n;j++) //前缀和最好下标从1开始
{
s[i][j]=s[i][j-1]+(q[j].y==i);
}
}
int cnt=-1,res;
for(int i=1;i<=n;i++)
{
int t=s[0][i-1]+s[1][n]-s[1][i-1];
if(t>=cnt)cnt=t,res=q[i].x;
//cout<<"t:"<<t<<" "<<"res:"<<res<<endl;
while(i+1<=n&&q[i+1].x==q[i].x)i++;
}
cout<<res<<endl;
return 0;
}