//Bài toán: Cho n số nguyên dương (n<20) và giá trị S. In ra mọi tập con có tổng đúng bằng S.
#include <bits/stdc++.h>
using namespace std;
int n, S;
vector<int> a;
vector<int> chosen;
vector<long long> suffixSum; // suffixSum[i] = a[i] + ... + a[n-1]
void backtrack(int i, long long curSum) {
// Cắt tỉa (pruning) để giảm độ phức tạp: tổng vượt quá S rồi thì không cần xét thêm vào phần tử nào nữa
if (curSum > S) return;
// Cắt tỉa (pruning) để giảm độ phức tạp:: dù lấy hết phần còn lại cũng không đủ S, không cần xét tiếp nữa
if (i < n && curSum + suffixSum[i] < S) return;
// Điều kiện dừng : Nếu đạt đúng S → in kết quả
if (curSum == S) {
for (int x : chosen) cout << x << " ";
cout << "\n";
// Không return ngay, vì có thể còn số 0 phía sau (nếu đề cho)
// Nhưng vì bài toán là số nguyên dương → có thể return để tối ưu
return;
}
// Nếu đã xét hết phần tử
if (i == n) return;
// CHỌN a[i]
chosen.push_back(a[i]);
// GỌI ĐỆ QUY
backtrack(i + 1, curSum + a[i]);
// BỎ CHỌN a[i] (undo state)
chosen.pop_back();
//GỌI ĐỆ QUY TRƯỜNG HỢP KHÔNG CHỌN a[i]
backtrack(i + 1, curSum);
}
int main() {
cin >> n >> S;
a.resize(n);
for (int i = 0; i < n; i++) cin >> a[i];
// Tính suffix sum
suffixSum.assign(n, 0);
suffixSum[n - 1] = a[n - 1];
for (int i = n - 2; i >= 0; i--)
suffixSum[i] = suffixSum[i + 1] + a[i];
backtrack(0, 0);
}
Ly9Cw6BpIHRvw6FuOiBDaG8gbiBz4buRIG5ndXnDqm4gZMawxqFuZyAobjwyMCkgdsOgIGdpw6EgdHLhu4sgUy4gSW4gcmEgbeG7jWkgdOG6rXAgY29uIGPDsyB04buVbmcgxJHDum5nIGLhurFuZyBTLgojaW5jbHVkZSA8Yml0cy9zdGRjKysuaD4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCmludCBuLCBTOwp2ZWN0b3I8aW50PiBhOwp2ZWN0b3I8aW50PiBjaG9zZW47CnZlY3Rvcjxsb25nIGxvbmc+IHN1ZmZpeFN1bTsgLy8gc3VmZml4U3VtW2ldID0gYVtpXSArIC4uLiArIGFbbi0xXQoKdm9pZCBiYWNrdHJhY2soaW50IGksIGxvbmcgbG9uZyBjdXJTdW0pIHsKICAgIC8vIEPhuq90IHThu4lhIChwcnVuaW5nKSDEkeG7gyBnaeG6o20gxJHhu5kgcGjhu6ljIHThuqFwOiB04buVbmcgdsaw4bujdCBxdcOhIFMgcuG7k2kgdGjDrCBraMO0bmcgY+G6p24geMOpdCB0aMOqbSB2w6BvIHBo4bqnbiB04butIG7DoG8gbuG7r2EKICAgIGlmIChjdXJTdW0gPiBTKSByZXR1cm47CgogICAgLy8gQ+G6r3QgdOG7iWEgKHBydW5pbmcpIMSR4buDIGdp4bqjbSDEkeG7mSBwaOG7qWMgdOG6oXA6OiBkw7kgbOG6pXkgaOG6v3QgcGjhuqduIGPDsm4gbOG6oWkgY8Wpbmcga2jDtG5nIMSR4bunIFMsIGtow7RuZyBj4bqnbiB4w6l0IHRp4bq/cCBu4buvYQogICAgaWYgKGkgPCBuICYmIGN1clN1bSArIHN1ZmZpeFN1bVtpXSA8IFMpIHJldHVybjsKCiAgICAvLyDEkGnhu4F1IGtp4buHbiBk4burbmcgOiBO4bq/dSDEkeG6oXQgxJHDum5nIFMg4oaSIGluIGvhur90IHF14bqjCiAgICBpZiAoY3VyU3VtID09IFMpIHsKICAgICAgICBmb3IgKGludCB4IDogY2hvc2VuKSBjb3V0IDw8IHggPDwgIiAiOwogICAgICAgIGNvdXQgPDwgIlxuIjsKICAgICAgICAvLyBLaMO0bmcgcmV0dXJuIG5nYXksIHbDrCBjw7MgdGjhu4MgY8OybiBz4buRIDAgcGjDrWEgc2F1IChu4bq/dSDEkeG7gSBjaG8pCiAgICAgICAgLy8gTmjGsG5nIHbDrCBiw6BpIHRvw6FuIGzDoCBz4buRIG5ndXnDqm4gZMawxqFuZyDihpIgY8OzIHRo4buDIHJldHVybiDEkeG7gyB04buRaSDGsHUKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gTuG6v3UgxJHDoyB4w6l0IGjhur90IHBo4bqnbiB04butCiAgICBpZiAoaSA9PSBuKSByZXR1cm47CgogICAgLy8gQ0jhu4xOIGFbaV0gCiAgICBjaG9zZW4ucHVzaF9iYWNrKGFbaV0pOwogICAgLy8gR+G7jEkgxJDhu4YgUVVZCiAgICBiYWNrdHJhY2soaSArIDEsIGN1clN1bSArIGFbaV0pOwogICAgLy8gQuG7jiBDSOG7jE4gYVtpXSAodW5kbyBzdGF0ZSkKICAgIGNob3Nlbi5wb3BfYmFjaygpOwogICAgCiAgICAvL0fhu4xJIMSQ4buGIFFVWSBUUsav4bucTkcgSOG7olAgS0jDlE5HIENI4buMTiBhW2ldCiAgICBiYWNrdHJhY2soaSArIDEsIGN1clN1bSk7Cn0KCmludCBtYWluKCkgewogICAgY2luID4+IG4gPj4gUzsKICAgIGEucmVzaXplKG4pOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIGNpbiA+PiBhW2ldOwoKCiAgICAvLyBUw61uaCBzdWZmaXggc3VtCiAgICBzdWZmaXhTdW0uYXNzaWduKG4sIDApOwogICAgc3VmZml4U3VtW24gLSAxXSA9IGFbbiAtIDFdOwogICAgZm9yIChpbnQgaSA9IG4gLSAyOyBpID49IDA7IGktLSkKICAgICAgICBzdWZmaXhTdW1baV0gPSBzdWZmaXhTdW1baSArIDFdICsgYVtpXTsKCiAgICBiYWNrdHJhY2soMCwgMCk7Cn0=