Codeforces Round #716 (Div. 2) D(随机算法)

博客内容讲述了在Codeforces Round #716 (Div.2) D问题中,如何处理区间查询并找出使得最多数不超过总数一半的最少部分。文章介绍了使用随机算法来寻找超过一半的数(众数),并通过贪心策略确定最优分割方案。算法涉及随机化、莫队算法、分块和线段树等数据结构与算法思想。
摘要由CSDN通过智能技术生成

Codeforces Round #716 (Div. 2) D
在这里插入图片描述
题意:区间查询,问区间最少能分成几部分使得最多的数不超过总数的一半 向上取整。
思路:找到区间的总数s,如果不超过一半的话就是一部分。超过一半的话,那我们只要考虑超过一半的那一个数怎么组合,超过一半的数为f,那f和其他一个数组合,剩下的f就单独,用贪心的思想可以看出这是最优的,那么答案就是 2*ans-(r-l+1);那我们怎么求众数呢,可以用莫队,分块,线段树,这里还可以用随机算法,因为f是超过一半的,那我们随机 k次 ,可以随机不到f的概率是 (1/2)^k ,当k等于 40 50 的时候 这个概率是几乎不可能的。

#include<bits/stdc++.h>
using namespace std;
int n,q,l,r,a[300005];
vector<int> v[300005];
#define all(v) (v).begin(),(v).end()
int main() {
	srand(time(NULL));
	scanf("%d%d",&n,&q);
	for(int i=1;i<=n;i++) {
		scanf("%d",a+i);
		v[a[i]].push_back(i);
	}
	for(int i=1;i<=q;i++) {
		scanf("%d%d",&l,&r);
		int ans=0;
		for(int j=1;j<=40;j++) {
			int id=a[rand()*rand()%(r-l+1)+l];
			ans=max(ans,int(upper_bound(all(v[id]),r)-lower_bound(all(v[id]),l)));
		}
		cout<<max(1,ans+ans-(r-l+1))<<endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值