51nod-1686 第K大区间

原题链接

基准时间限制:1 秒 空间限制:131072 KB 分值: 40  难度:4级算法题
 收藏
 关注

定义一个区间的值为其众数出现的次数
现给出n个数,求将所有区间的值排序后,第K大的值为多少。


众数(统计学/数学名词)_百度百科 

Input
第一行两个数n和k(1<=n<=100000,k<=n*(n-1)/2)
第二行n个数,0<=每个数<2^31
Output
一个数表示答案。
Input示例
4 2
1 2 3 2
Output示例
2
二分答案t,统计众数出现次数大于等于t的区间有多少个。
枚举右端点R,计算左端点L最大为多少,使得区间[L,R]的值大于等于t,对于每个R他对答案贡献为L。

#include <bits/stdc++.h>
#define maxn 100005
using namespace std;
typedef long long ll;

vector<int> v[maxn];
int num1[maxn], num2[maxn], p[maxn];
ll n, k, len;
bool judge(int m){
	
	ll ans = 0;
	int kk = -1;
	for(int i = 0; i < n; i++){
		int d = lower_bound(num2, num2+len, num1[i]) - num2;
		p[d]++;
		if(p[d] >= m){
			kk = max(kk, v[d][p[d]-m]);
		}
		if(kk != -1){
			ans += kk + 1;
		}
		if(ans >= k)
		 return true;
	}
	return false;
}
int main(){
	
//	freopen("in.txt", "r", stdin);
	scanf("%I64d%I64d", &n, &k);
	for(int i = 0; i < n; i++){
	 scanf("%d", num1+i);
	 num2[i] = num1[i];
    }
	sort(num2, num2+n);
	len = unique(num2, num2+n) - num2;
	for(int i = 0; i < n; i++){
		int e = lower_bound(num2, num2+len, num1[i]) - num2;
		v[e].push_back(i);
	}
	int l = 1, r = n+1;
	while(l < r){
		memset(p, 0, sizeof(p));
		int mid = (l + r) >> 1;
		if(judge(mid) == false)
		 r = mid;
		else
		 l = mid + 1;
	}
	printf("%d\n", l - 1);
	
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值