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 
m2 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!

题意:每个细胞每天增量为一,问最少多少天可以增加到总量为n。

  每一个细胞可以选择在白天的时候分裂或者不分裂,而晚上的增量就是白天的细胞总数量。因为每次最多是二倍的增加,所以很容易想到对n进行二进制分解。增量最多的情况就是指数增长,第一天变成2个,增量为2,第二天变成4个,增量为4……第n天变成2n,增量为2n,而如果n恰好是2+4+……+2x,那么最少天数就是x天,那么如果剩下了y天又该怎么办呐?我们可以把y插入这个2的幂次的序列里,假如2i<=y<=2i+1,那么把y插入他们俩中间,第i天的细胞数是2i,第i+1天使细胞数量是y,第i+2天使细胞数量数2i+1,这样天数变成x+1天,增量就是n啦。

  注意:每一天的细胞数就是当天的增量,所以n是每天的细胞数的和。

代码:

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<vector>
#define ll long long 
using namespace std;
int n,t;
int ans;
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		vector<int>v;
		ll sum=0;int ans=0;
		for(int i=0;;i++)
		{
			if((1<<i)<=n)
			{
				v.push_back(1<<i);//记录每天的细胞数
				n-=(1<<i);
			}
			else break;
		}
		if(n)
		{
			v.push_back(n);
			sort(v.begin(),v.end());//把剩下的一个加入序列,然后排序,其实用小根堆也可以
		}
		printf("%d\n",v.size()-1);
		for(int i=1;i<v.size();++i)
			printf("%lld ",v[i]-v[i-1]);//因为所求是每天分裂数,所以是当天细胞数减前一天的细胞数
		printf("\n");
	}
	return 0;
}