CF1077D Cutting Out(二分)
题意:
给出一串序列,请你找出一个大小为k的元素集合,使得可以在这个序列中找到数量最大的集合拷贝。
题解:
一开始想到背包去了,其实不用这么麻烦,以拷贝数为条件做一个二分查找,时间复杂度nlogn。
#include<bits/stdc++.h> using namespace std; const int maxn=2e5+100; int n,k; int a[maxn]; int pos[maxn]; int main () { cin>>n>>k; for (int i=1;i<=n;i++) scanf("%d",&a[i]); for (int i=1;i<=n;i++) pos[a[i]]++; int l=1,r=2e5+10; int ans=0; while (l<=r) { int mid=(l+r)>>1; int sum=0; for (int i=1;i<=2e5;i++) sum+=pos[i]/mid; if (sum>=k) l=mid+1,ans=mid; else r=mid-1; } //printf("%d\n",ans); int tot=0; for (int i=1;i<=2e5+10;i++) { for (int j=1;j<=pos[i]/ans&&++tot<=k;j++) printf("%d ",i); } }