题意:n个工人,m个工作,每个人做自己的工作需要1小时,做别人的工作需要2小时,求完成m个工作需要的最短时间是多少
分析:求最小用二分,选取一个mid的时间,如果每个员工自己的工作时间大于mid,sum直接加上mid,若小于mid,他在mid时间里能做工作个数为自己的工作数加上(mid-自己工作数)/2,最后的总数如果大于等于m ,说明mid时间做这些事情绰绰有余,则我们可以把mid缩短,继续二分,直到找到最小mid
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e6+10;
ll a[N];
ll n,m;
map<ll,ll>mp;
bool juge(ll mid){
ll sum=0;
for(int i=1;i<=n;i++){
if(mp[i]>mid)sum+=mid;
else sum+=mp[i]+(mid-mp[i])/2;
}
if(sum>=m)return true;
else return false;
}
int main(){
int t;
cin>>t;
while(t--){
cin>>n>>m;
mp.clear();
for(int i=1;i<=m;i++){
cin>>a[i];
mp[a[i]]++;
}
ll l=1,r=m;
while(l<=r){
ll mid=(l+r)/2;
if(juge(mid))r=mid-1;
else l=mid+1;
}
cout<<l<<endl;
}
return 0;
}