题意:中文题,定义一个区间的值为其众数出现的
次数。
现给出n个数,求将所有区间的值排序后,第K大的值为多少。
离散化二分答案加尺取判断
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 100006;
typedef long long ll;
int len;
int num[maxn];
int tmp[maxn];
int vis[maxn];
int id[maxn];
int n;
ll k;
bool check(int mid)
{
int flag = 0;
int l=0,r=0; ll ans = 0;
memset(vis,0,sizeof(vis));
while(r<=n){
if(flag ==0)
{
if(r==n) break;
vis[id[r]] ++;
if(vis[id[r]]>=mid) flag = 1;
r++;
}
else
{
while(flag!=0)
{
ans += n-r+1;
vis[id[l]]--;
l++;
if(vis[id[r-1]]<mid) flag = 0;
}
}
}
if(ans>=k) return true;
return false;
}
int main()
{
scanf("%d%I64d",&n,&k);
for(int i=0;i<n;i++) {scanf("%d",&num[i]); tmp[i] = num[i];}
sort(tmp,tmp+n);
len = 0;
for(int i=1;i<n;i++)
{
if(tmp[i]!=tmp[i-1]) tmp[++len] = tmp[i];
}
len++;
for(int i=0;i<n;i++)
{
id[i] = lower_bound(tmp,tmp+len,num[i])-tmp;
}
int l = 1,r = n,mid;
while(l<=r)
{
mid = (l+r)/2;
bool flag = check(mid);
//printf("sgdgghm\n");
if(flag) l = mid+1;
else r=mid-1;
}
printf("%d\n",r);
return 0;
}