Codeforces 1303 D. Fill The Bag (binary greedy)

Description:

You have a bag of size n n . Also you have m boxes. The size of i t h I th box is a i a_{i} , where each ai is an integer non-negative power of two.

You can divide boxes into two parts of equal size. Your goal is to fill the bag completely.

For example, if n = 10 n=10 and a = [ 1 , 1 , 32 ] a=[1,1,32] then you have to divide the box of size 32 into two parts of size 16 16 , and then divide the box of size 16. So you can fill the bag with boxes of size 1 , 1 1, 1 and 8 8 .

Calculate the minimum number of divisions required to fill the bag of size n.

Input

The first line contains one integer t ( 1 t 1000 ) t (1≤t≤1000) — the number of test cases.

The first line of each test case contains two integers n n and m m ( 1 n 1 0 18 , 1 m 1 0 5 ) (1≤n≤10^{18},1≤m≤10^5) — the size of bag and the number of boxes, respectively.

The second line of each test case contains m integers a 1 , a 2 , , a m ( 1 a i 1 0 9 ) a_{1},a_{2},…,a_{m} (1≤a_{i}≤10^9) — the sizes of boxes. It is guaranteed that each ai is a power of two.

It is also guaranteed that sum of all m over all test cases does not exceed 1 0 5 10^5 .

Output

For each test case print one integer — the minimum number of divisions required to fill the bag of size n n (or −1, if it is impossible).

Example

input

3
10 3
1 32 1
23 4
16 1 4 1
20 5
2 1 16 1 8

output

2
-1
0

Meaning of the questions:

Give you a sequence, you can ask a combination n n , where you can put a number into two equal-size portions, you ask minimum number of operations.
A situation that can not make up all add up to less than or n n , then we started greedy, if this number is smaller than the descending quality Then go directly into the backpack, if the quality is larger than the backpack and backpack filled up the rest of the quality we operate once, or we abandon this article.

AC Code:

#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <stack>
#include <queue>
using namespace std;
#define sd(n) scanf("%d", &n)
#define sdd(n, m) scanf("%d%d", &n, &m)
#define sddd(n, m, k) scanf("%d%d%d", &n, &m, &k)
#define pd(n) printf("%d\n", n)
#define pc(n) printf("%c", n)
#define pdd(n, m) printf("%d %d\n", n, m)
#define pld(n) printf("%lld\n", n)
#define pldd(n, m) printf("%lld %lld\n", n, m)
#define sld(n) scanf("%lld", &n)
#define sldd(n, m) scanf("%lld%lld", &n, &m)
#define slddd(n, m, k) scanf("%lld%lld%lld", &n, &m, &k)
#define sf(n) scanf("%lf", &n)
#define sc(n) scanf("%c", &n)
#define sff(n, m) scanf("%lf%lf", &n, &m)
#define sfff(n, m, k) scanf("%lf%lf%lf", &n, &m, &k)
#define ss(str) scanf("%s", str)
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = n; i >= a; i--)
#define mem(a, n) memset(a, n, sizeof(a))
#define debug(x) cout << #x << ": " << x << endl
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define mod(x) ((x) % MOD)
#define gcd(a, b) __gcd(a, b)
#define lowbit(x) (x & -x)
typedef pair<int, int> PII;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int MOD = 1e9 + 7;
const double eps = 1e-9;
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const int inf = 0x3f3f3f3f;
inline int read()
{
    int ret = 0, sgn = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            sgn = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
    {
        ret = ret * 10 + ch - '0';
        ch = getchar();
    }
    return ret * sgn;
}
inline void Out(int a) //Êä³öÍâ¹Ò
{
    if (a > 9)
        Out(a / 10);
    putchar(a % 10 + '0');
}

ll gcd(ll a, ll b)
{
    return b == 0 ? a : gcd(b, a % b);
}

ll lcm(ll a, ll b)
{
    return a * b / gcd(a, b);
}
///快速幂m^k%mod
ll qpow(ll a, ll b, ll mod)
{
    if (a >= mod)
        a = a % mod + mod;
    ll ans = 1;
    while (b)
    {
        if (b & 1)
        {
            ans = ans * a;
            if (ans >= mod)
                ans = ans % mod + mod;
        }
        a *= a;
        if (a >= mod)
            a = a % mod + mod;
        b >>= 1;
    }
    return ans;
}

// 快速幂求逆元
int Fermat(int a, int p) //费马求a关于b的逆元
{
    return qpow(a, p - 2, p);
}

///扩展欧几里得
int exgcd(int a, int b, int &x, int &y)
{
    if (b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    int g = exgcd(b, a % b, x, y);
    int t = x;
    x = y;
    y = t - a / b * y;
    return g;
}

///使用ecgcd求a的逆元x
int mod_reverse(int a, int p)
{
    int d, x, y;
    d = exgcd(a, p, x, y);
    if (d == 1)
        return (x % p + p) % p;
    else
        return -1;
}

///中国剩余定理模板0
ll china(int a[], int b[], int n) //a[]为除数,b[]为余数
{
    int M = 1, y, x = 0;
    for (int i = 0; i < n; ++i) //算出它们累乘的结果
        M *= a[i];
    for (int i = 0; i < n; ++i)
    {
        int w = M / a[i];
        int tx = 0;
        int t = exgcd(w, a[i], tx, y); //计算逆元
        x = (x + w * (b[i] / t) * x) % M;
    }
    return (x + M) % M;
}

ll n;
ll m;
const int N = 1e5 + 10;
ll a[N], sum, ans;
int main()
{
    int t;
    sd(t);
    while (t--)
    {
        sldd(n, m);
        sum = 0;
        rep(i, 1, m)
        {
            sld(a[i]);
            sum += a[i];
        }
        if (sum < n)
        {
            puts("-1");
            continue;
        }
        sort(a + 1, a + m + 1);
        ans = 0;
        while (m)
        {
            if (a[m] <= n)
            {
                n -= a[m];
                sum -= a[m--];
            }
            else if (sum - a[m] < n)
            {
                a[m] /= 2;
                a[m + 1] = a[m];
                m++;
                ans++;
            }
            else
                sum -= a[m--];
            //cout << m << " " << a[m] << endl;
        }
        pld(ans);
    }
    return 0;
}

Published 679 original articles · won praise 410 · views 210 000 +

Guess you like

Origin blog.csdn.net/qq_43627087/article/details/104299370