本题是一道很妙的二分题目,这很二分。最开始本萌新想的解法是很基础死板的二分,就是把m个数组排序,然后分成n份,二分时间,取n份中时间的最大值。但后来发现有很多情况都不适用。应该再加上贪心的优化。所以我们应该让有对应数值的优先取,而后多余的再交给其它人做。
代码如下:
#include<stdio.h>
#include<iostream>
#include<map>
#include<algorithm>
#include<string.h>
#include<queue>
#include<vector>
#include<unordered_map>
using namespace std;
typedef long long ll;
ll l,r,mid;
ll n,m;
ll b[200005];
ll c[200005];
bool check(ll x){
int sum=0;
for(int i=1;i<=n;i++){
if(c[i]>=x){
sum+=c[i]-x;
}
else{
sum-=(x-c[i])/2;
}
}
return sum<=0;
}
int main(){
ios::sync_with_stdio(false);
cin.tie();
cout.tie();
int t;
cin>>t;
while(t--){
cin>>n>>m;
for(int i=1;i<=n;i++){
c[i]=0;
}
for(int i=1;i<=m;i++){
cin>>b[i];
c[b[i]]++;
}
l=1;
r=(m+n-1)/n*2;
sort(b+1,b+1+m);
while(l<r){
mid=(l+r)>>1;
if(check(mid)){
r=mid;
}
else{
l=mid+1;
}
}
cout<<l<<"\n";
}
}