题目链接
- 难以直接求解。考虑用二分答案转化为判定(根据复杂度理论,判定的难度小于求解)。
- 当你想不到一个更新的视角看待问题时,不妨回顾一下你已有的想法,正解说不定就隐藏其中,只需要再深入一些
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int a[2005],b[2005][2005],v[2][2005][2005];
priority_queue<int>qxiao;
priority_queue<int,vector<int>,greater<int> >qda;
int len;
void clear()
{
len=0;
while(qxiao.size())
{
qxiao.pop();
}
while(qda.size())
{
qda.pop();
}
}
void update(int x)
{
if(len%2==0)
{
if(qda.empty()||x<=qda.top())
{
qxiao.push(x);
}
else
{
qxiao.push(qda.top());
qda.pop();
qda.push(x);
}
}
else
{
if(qxiao.empty()||x>=qxiao.top())
{
qda.push(x);
}
else
{
qda.push(qxiao.top());
qxiao.pop();
qxiao.push(x);
}
}
len++;
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=n;i++)
{
clear();
for(int j=i;j<=n;j++)
{
update(a[j]);
b[i][j]=qxiao.top();
}
}
int l=1,r=1000000000;
while(l<r)
{
int mid=(l+r)>>1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
v[0][i][j]=v[0][i-1][j]+v[0][i][j-1]-v[0][i-1][j-1];
v[1][i][j]=v[1][i-1][j]+v[1][i][j-1]-v[1][i-1][j-1];
if(i>j)
{
continue;
}
v[0][i][j]+=(b[i][j]<=mid);
v[1][i][j]+=(b[i][j]>=mid);
}
}
int val0=0,val1=0;
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
int v0=v[0][j][j]-v[0][i-1][j]-v[0][j][i-1]+v[0][i-1][i-1];
int v1=v[1][j][j]-v[1][i-1][j]-v[1][j][i-1]+v[1][i-1][i-1];
int m=j-i+1;
int tot=m*(m-1)/2+m;
val0+=(v0>=(tot+1)/2);
val1+=(v1>=tot-(tot+1)/2+1);
}
}
if(val0>=val1)
{
r=mid;
int tot=n*(n-1)/2+n;
if(val0>=(tot+1)/2&&val1>=tot-(tot+1)/2+1)
{
cout<<mid<<endl;
return 0;
}
r--;
}
else
{
l=mid;
int tot=n*(n-1)/2+n;
if(val0>=(tot+1)/2&&val1>=tot-(tot+1)/2+1)
{
cout<<mid<<endl;
return 0;
}
l++;
}
}
cout<<l<<endl;
return 0;
}