思路:分解数ans的上限为1的数目,加如可以分解为x组,其中x<count[1],那么[x,count[1]]的都可以作为答案,因为将1提取出来又是新的一组。那么可以二分出可分解的最小组数。
# include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+3;
int a[maxn]={0}, b[maxn]={0};//a[i]为2^i个数,b[i]为2^i~2^i+1个数。
bool judge(int x)
{
int t = a[0]-x+b[0];//非法数字。
for(int i=1; i<50; ++i)
{
if(a[i] <= x)//表示这里要断开了。
{
t -= min(t, x-a[i]);//捎上非法数字再断开。
x = a[i];//有效组数减少为a[i]。
}
else
t += a[i]-x;
t += b[i];
}
return t<=x;
}
int main()
{
int n;
LL m;
scanf("%d",&n);
while(n--)
{
scanf("%I64d",&m);
int c=0;
bool f = true;
while(m>1)
{
if(m&1) f = false;
m>>=1;
++c;
}
if(!f) ++b[c];
else ++a[c];
}
int l=ceil(a[0]*1.0/2), r=a[0];
while(l<r)
{
int mid = l+r>>1;
if(judge(mid)) r=mid;
else l = mid+1;
}
if(!judge(r)) return 0*puts("-1");
else
for(int i=r; i<=a[0]; ++i) printf("%d ",i);
puts("");
return 0;
}