+ Greedy binary split --cf1303D

/*
N first binary split map stored with a [i] Occurrences
From low to high and then to join n
For i 1 n by the number of bits of 
    Mp consider whether there 1 << i 
    If not, consider mp where i can Couchu lower than the number i, 
    If you still can not, from a high level to dismantle, only in this case, the answer will be to contribute
*/
#include<bits/stdc++.h>
using namespace std;
#define ll long long 
ll n,m,a[100005],b[65];
map<ll,ll>mp;

int main(){
    int t;cin>>t;
    while(t--){
        cin>>n>>m;
        mp.clear();
        memset(b,0,sizeof b);
        
        ll sum=0;
        for(int i=1;i<=m;i++)
            cin>>a[i],mp[a[i]]++,sum+=a[i];
        for(int i=60;i>=0;i--)if((n>>i) & 1)b[i]=1;
            
        if(sum<n){puts("-1");continue;}
        
        ll ans=0;
        ll tot=0;//多余量 
        for(int i=0;i<=60;i++)
            if(b[i]){
                if(mp[(1ll<<i)]){
                    mp[(1ll<<i)]--;
                    tot+=(1ll<<i)*mp[(1ll<<i)];
                    mp[(1ll<<i)]=0;
                }
                the else  IF (TOT> = (1LL << I)) { // can scrape the excess amount in the 
                    TOT - = (1LL << I);
                }
                the else { // must be removed from a high order 
                    LL = CUR (1LL << I);
                    ll j=cur;
                    while(1){
                        if(mp[j]!=0){
                            mp[j]--;
                            break;
                        }
                        j<<=1;
                    } 
                    while(j!=cur){
                        years ++ ;
                        j>>=1;
                        Mp [J] Tasutasu ;
                    }
                    all + = cur;
                }
            }else {
                tot+=mp[(1ll<<i)]*(1ll<<i);
            }
        cout<<ans<<'\n'; 
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/zsben991126/p/12302048.html