https://codeforces.com/contest/1348/problem/D

题意:

初始有一个细菌,重量为1。每个细菌白天可以分裂成两个,重量均为原来的一半。每个夜晚,每个细菌会增加1重量

现在你可以决定每个白天有几个细菌分裂,问至少经过几晚细菌的总重量恰为n。输出每天有几个细菌分裂

思路:

分裂不会增加总重量,故只用考虑夜晚增加的重量

贪心。假设前 d 天每个细菌都分裂,那么第 d 夜后总重量为 \(1(初始重量)+2^2+2^2+\cdots 2^d = 2^{d+1}-1\)

还需要 \(k=n-(2^{d+1}-1)\) 。注意到每晚增加的重量不小于前一晚增加的重量,所以 k 不能在最后一晚,而应插入到中间的一个位置使数组递增。实测用 sort 排序跟手动插入速度一样

#include <bits/stdc++.h>
using namespace std;

int a[35];

signed main()
{
    int T; scanf("%d", &T); while(T--)
    {
        int n, d; scanf("%d", &n);
        for(d = 0; (1<<d)-1 < n; d++) a[d] = 1<<d;
        a[d-1] = n+1-a[d-1];
        sort(a, a+d);
        printf("%d\n", d - 1);
        for(int i = 1; i < d; i++)
            printf("%d ", a[i]-a[i-1]);
        puts("");
    }

    return 0;
}