题目链接:https://codeforc.es/contest/1701/problem/C

一个青名题。二分类型

大意是,给出n个人编号  1-n,然后给出m个任务,每个任务a[i]对应一个值,这个值在1-n内,含义是a[i]这个人做这个任务时擅长的。
如果一个人去做他擅长的任务,那么他需要一个小时,否则需要两个小时。
n个人同时进行任务,求所需最短时间。

做法:有些二分逼近的思想。我们取一个mid去中和,比mid大的,我们记录出来,然后*2,这些需要用比mid小的任务数的人来中和
一次次逼近,直到最终答案。特别的,如果任务数小的那个人剩余可处理任务数是个奇数,则他能够提供的帮助要减少1,可以默认的是,
他所做的最后一次的奇数个任务所用的时间是2.

code:

#include<bits/stdc++.h>
using namespace std;
const int N=200005;
int n,m,f[N],t,x;
long long a,b;
int main(){
	cin>>t;
	for(;t--;){
		scanf("%d%d",&m,&n);
		for(int i=1;i<=n;i++)scanf("%d",&x),f[x]++;
		int l=1,r=n,mid;
		while(l<=r){
			mid=l+r>>1;
			a=b=0;
			for(int i=1;i<=m;i++)
				if(mid<=f[i])
					a+=(f[i]-mid)*2;
				else 
					b+=(mid-f[i])%2?mid-f[i]-1:mid-f[i];
			if(a>b)l=mid+1;
			else r=mid-1;
		}
		printf("%d\n",l);
		for(int i=1;i<=m;i++)f[i]=0;
	}
}