Link to this code: https://cses.fi/paste/39bb411c336d08d8f6c8f1/
/**
 *    author: TomDev - Tran Hoang Quan
 *    created: 2026-02-05 23:10:35
 *    country: Vietnam - VNM
 *    title: Meet in the Middle
 *    source: https://cses.fi/problemset/task/1628/
 *    submission: 
 * ----------------------------------------------------------
 *    tags: Dynamic Programming, Implementation, Optimization
 *    complexity: O(2^{\frac{n}{2}}*log{\frac{n}{2}} + 2^{\frac{n}{2}}*log{\frac{n}{2}})
 *    note: 
 *    1. We can divide our array into two halves, and then bitmask on the first half to find all the possible sums, we call every sum in this subset is A
 *    2. For the second half, we can do the same bitmask, call every sum in this second subset B, but now we find if the x-B is available in the first half? => x-B = A
 *    3. We can find out that if it is available by using map or unordered_map, but both of them are slow with a contant in the time complexity, so we can save them all into a vector with only 2^{\frac{n}{2}} elements, then we can count the occurences by using the upper_bound index - lower_bound index of x-B
**/

#include <iostream>
#include <vector>
#include <cstdio>
#include <utility>
#include <algorithm>
#if __has_include("debuggingz.h")
    #include "debuggingz.h"
    #define dbg(x,i) cerr << "BreakPoint(" << i << ") -> " << #x << " = " << (x) << '\n';
#else
    #define dbg(x,i)
#endif

using namespace std;

#define all(x,bonus) (x).begin()+(bonus),(x).end()
#define rall(x,bonus) (x).rbegin(),(x).rend()-(bonus)
#define fastio ios_base::sync_with_stdio(false);cin.tie(NULL);
#define fi first
#define se second
#define eb emplace_back
#define sz(x) (int)(x).size()
using ll = long long;
using ld = long double;
using pll = pair<long long,long long>;
using pld = pair<long double,long double>;
using ull = unsigned long long;
using pii = pair<int,int>;
using vi = vector<int>;
using vii = vector<vector<int>>;
using vll = vector<long long>;
using vlll = vector<vector<long long>>;

void setup(){
    if(!fopen("NAME.INP", "r")) return;
    freopen("NAME.INP", "r", stdin);
    freopen("NAME.OUT", "w", stdout);
}

// ----------------------- [ CONFIG & CONSTANTS ] -----------------------


// ----------------------- [ FUNCTIONS ] -----------------------


// ----------------------- [ MAIN ] -----------------------
int main(){
    fastio;
    setup();

    int n,s;
    cin >> n >> s;

    int mid = n>>1;
    vi a(n+1);
    for(int i = 1; i <= n; i++) cin >> a[i];
    vi tot;
    tot.reserve(1 << mid);

    for(int mask = 0; mask < (1 << mid); mask++){
        int sum = 0;
        for(int j = mask; j > 0; j &= (j-1)){
            sum += a[__builtin_ctz(j)+1];
            if(sum > s) break;
        }   
        if(sum <= s) tot.eb(sum);
    }

    ll ans = 0;
    sort(all(tot,0));
    for(int mask = 0; mask < (1 << (n-mid)); mask++){
        int sum = 0;
        for(int j = mask; j > 0; j &= (j-1)){
            sum += a[__builtin_ctz(j)+1+mid];
            if(sum > s) break;
        }
        if(sum <= s){
            int it = lower_bound(all(tot,0), s-sum) - tot.begin();
            if(tot[it] == s-sum) ans += upper_bound(all(tot,0),s-sum) - tot.begin() - it;
        }
    }
    cout << ans;
}