Problem Description
As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them:
Yuta has n positive A1−An and their sum is m. Then for each subset S of A, Yuta calculates the sum of S.
Now, Yuta has got 2n numbers between [0,m]. For each i∈[0,m], he counts the number of is he got as Bi.
Yuta shows Rikka the array Bi and he wants Rikka to restore A1−An.
It is too difficult for Rikka. Can you help her?
Input
The first line contains a number t(1≤t≤70), the number of the testcases.
For each testcase, the first line contains two numbers n,m(1≤n≤50,1≤m≤104).
The second line contains m+1 numbers B0−Bm(0≤Bi≤2n).
Output
For each testcase, print a single line with n numbers A1−An.
It is guaranteed that there exists at least one solution. And if there are different solutions, print the lexicographic minimum one.
Sample Input
2
2 3
1 1 1 1
3 3
1 3 3 1
Sample Output
1 2
1 1 1
Hint
In the first sample,
A
is
Source
2017 Multi-University Training Contest - Team 5
Recommend
liuyiding | We have carefully selected several similar problems for you: 6119 6118 6117 6116 6115
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define ms(a,b) memset(a,b,sizeof(a))
using namespace std;
#define ll long long int
const int maxn = 1e4 + 100;
ll b[maxn];
int dp[maxn], num[maxn];
int C(int n, int m)
{
int sum = 1;
for (int i = n - m + 1; i <= n; i++) sum *= i;
for (int i = 1; i <= m; i++) sum /= i;
return sum;
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
int n, m;
scanf("%d%d", &n, &m);
ms(dp, 0);
ms(num, 0);
for (int i = 0; i <= m; i++)
{
scanf("%lld", &b[i]);
}
num[0] = log2(b[0]);
num[1] = b[1] / b[0];
dp[0] = b[0];
for (int i = 0; i <= m; i++)
{
for (int j = m; j >= 0; j--)
{
if (dp[j] == 0) continue;
if (num[i] == 0) break;
for (int k = 1; k <= num[i]; k++)
{
if (j + k*i <= m)
{
dp[j + k*i] += dp[j] * C(num[i], k);
}
}
}
if (i + 1 <= m)
{
num[i + 1] = (b[i + 1] - dp[i + 1]) / b[0];
}
}
bool flag = 0;
for (int i = 0; i <= m; i++)
{
for (int j = 1; j <= num[i]; j++)
{
if (!flag) printf("%d", i), flag = 1;
else printf(" %d", i);
}
}
printf("\n");
}
return 0;
}