题解:
注意这里的数组a中的元素,全部都是2的整数幂。然后有二进制可以拼成任意数。只要一堆2的整数幂的和大于x,x也是2的整数幂,那么那一堆2的整数幂一定可以组成x。
思路:位运算,对每一位,如果该位置i是1的话,先考虑从0到该位置的,数组a的和,如果比(1<<i)的话,那么可以拼接,否则的话,需要从高位向下除,也就是从i+1位到58位,找到第一个再某一位置j上不为0的数
然后需要降j-i次幂。然后从j~i,每一位上数的个数都要+1。并且累加答案ans+=j-i;
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll p[100]; void solve(){ memset(p,0,sizeof p); ll n,m; cin>>n>>m; ll x; ll sum=0; for(ll i=1;i<=m;i++){ cin>>x; sum+=x; ll j=0; while(!((x>>j)&1)) j++; p[j]++; } if(sum<n) cout<<-1<<endl; else { ll ans=0,tmp=0; for(ll i=0;i<=58;i++) { if((n>>i)&1) { ll c=0; for(ll j=0;j<=i;j++) c+=p[j]*(1<<j); if(c-tmp>=(1<<i)) tmp+=(1<<i); else { ll poll=-1; for(ll j=i+1;j<=58;j++){ if(p[j]){ poll=j; break; } } ans+=poll-i; p[poll]--; for(ll k=poll-1;k>=i;k--) p[k]++; } } } cout<<ans<<endl; } } int main(){ ll t; cin>>t; while(t--) solve(); return 0; }