CodeForces_1348D Phoenix and Science(数论)

Phoenix and Science

time limit per test:2 seconds
memory limit per test:256 megabytes

Problem Description

Phoenix has decided to become a scientist! He is currently investigating the growth of bacteria.

Initially, on day 1, there is one bacterium with mass 1.

Every day, some number of bacteria will split (possibly zero or all). When a bacterium of mass m splits, it becomes two bacteria of mass m 2 \frac{m}{2} 2m each. For example, a bacterium of mass 3 can split into two bacteria of mass 1.5.

Also, every night, the mass of every bacteria will increase by one.

Phoenix is wondering if it is possible for the total mass of all the bacteria to be exactly n. If it is possible, he is interested in the way to obtain that mass using the minimum possible number of nights. Help him become the best scientist!

Input

The input consists of multiple test cases. The first line contains an integer t ( 1 ≤ t ≤ 1000 1≤t≤1000 1t1000) — the number of test cases.

The first line of each test case contains an integer n ( 2 ≤ n ≤ 1 0 9 2≤n≤10^9 2n109) — the sum of bacteria masses that Phoenix is interested in.

Output

For each test case, if there is no way for the bacteria to exactly achieve total mass n, print -1. Otherwise, print two lines.

The first line should contain an integer d — the minimum number of nights needed.

The next line should contain d integers, with the i-th integer representing the number of bacteria that should split on the i-th day.

If there are multiple solutions, print any.

Sample Input

3
9
11
2

Sample Output

3
1 0 2
3
1 1 2
1
0

题意

初始有一个质量为1的细胞,每天可以选择一部分细胞将其分裂为两个,质量为m个细胞会被分裂为两个质量为 m 2 \frac{m}{2} 2m的细胞。在每天的晚上,所有的细胞质量都会加1。
求是否存在分裂方案使细胞质量和为n,如果有输出需要天数最少的一种方案即可。

题解

可以发现实际上细胞的分裂,质量上的变化对结果并无影响,数量上的变化会对结果产生影响,所以只考虑,分裂后的细胞数量问题。
显然解是一定存在的,不分裂,n-1天质量和即为n。但是要求天数最少,考虑每天都将所有的细胞进行分裂。那么第 i i i天,细胞质量和最大为 2 i + 1 − 1 2^{i+1}-1 2i+11。求出满足 n ≤ 2 i + 1 n \le 2^{i+1} n2i+1的最小的 i i i,记为m,m即为最少的天数。
方案:将分裂看做原细胞质量不变,增加一个质量为0的新细胞(对细胞质量的和而言,他和原方案是一样的)。已知最少天数为m,则在第 i i i天产生的新细胞在第m天质量为 m − i + 1 m-i+1 mi+1。从第一天开始,枚举每天产生的新细胞数量即可。注意每天产生的新细胞的数量需小于等于之前的细胞数量。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define dbg(x) cout<<#x<<" = "<
#define INF 0x3f3f3f3f
#define eps 1e-6
 
using namespace std;
typedef long long LL;   
typedef pair<int, int> P;
const int maxn = 200100;
const int mod = 1000000007;
int a[maxn];

int main()
{
    int t, n, m, i, j, k;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d", &n);
        for(i=1;;i++)
            if(n < (1<<(i+1))){
                m = i;break;
            }
        int x = m+1, sum = 1;
        for(i=1;i<=m;i++){
            j = m-i+1;
            a[i] = min(sum, (n-x)/j);
            x += a[i]*j;
            sum += a[i];
        }
        printf("%d\n", m);
        for(j=1;j<m;j++)
            printf("%d ", a[j]);
        printf("%d\n", a[m]);
    }
    return 0;
}

你可能感兴趣的:(数论)