Problem:
Coin Combination Problem II
You have
N
coins each of which has a value
a
i
.
Find the number of combinations that result when you choose
K
different coins in such a way that the total value of the coins is greater than or equal to
L
and less than or equal to
R
.
Constraints
1 ≤
K
≤
N
≤ 40
1 ≤
a
i
≤ 10
16
1 ≤
L
≤
R
≤ 10
16
All input values are given in integers
Input
The input is given in the following format.
N
K
L
R
a
1
a
2
...
a
N
Output
Print the number of combinations in a line.
Sample Input 1
2 2 1 9
5 1
Sample Output 1
1
Sample Input 2
5 2 7 19
3 5 4 2 2
Sample Output 2
5

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ld = long double;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vvvi = vector<vector<vector<int>>>;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;
using vvvll = vector<vector<vector<ll>>>;
using vd = vector<double>;
using vvd = vector<vector<double>>;
using vstr = vector<string>;
using vchar = vector<char>;
using vvchar = vector<vector<char>>;
using vb = vector<bool>;
using vvb = vector<vector<bool>>;
using vvvb = vector<vector<vector<bool>>>;
using pii = pair<int,int>;
using pll = pair<long long, long long>;
using Graph = vector<vector<int>>;
using WeightedGraph = vector<vector<pair<int,ll>>>;
const int dx[8] = {1, 0, -1, 0, 1, 1, -1, -1};
const int dy[8] = {0, 1, 0, -1, 1, -1, 1, -1};

#define rep(i, a, b) for(ll i = (ll)a; i < (ll)b; i++)
#define REP(i, a, b) for (ll i = (ll)a; i <= (ll)b; i++)
#define rrep(i, a, b) for(ll i = (ll)b-1; i >= (ll)a; i--)
#define RREP(i, a, b) for(ll i = (ll)b; i >= (ll)a; i--)
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
#define YESNO(flag) cout << (flag ? "Yes" : "No") << "\n"
#define spa " "
#define mint modint<MOD>

const int inf = 1070000000;
const long long INF = 4500000000000000000;
//const long long MOD = 998244353;
const long long MOD = 1000000007;
const double pi = 3.141592653589793238;
const double eps = (1e-10);
const string ABC = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string abc = "abcdefghijklmnopqrstuvwxyz";

template<typename T> 
inline bool chmin(T& a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template<typename T> 
inline bool chmax(T& a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
template<typename S, typename T> 
pair<S, T> operator+(pair<S, T> a, pair<S, T> b) {
    pair<S, T> ans;
    ans.first = a.first + b.first;
    ans.second = a.second + b.second;
    return ans;
} 
template<typename T> 
vector<T> operator+(vector<T> a, vector<T> b) {
    int N = max(a.size(), b.size());
    vector<T> c(N);
    for(int i = 0; i < N; i++) {
        if(i >= a.size()) c[i] = b[i];
        else if(i >= b.size()) c[i] = a[i];
        else c[i] = a[i] + b[i];
    }
    return c;
}
template<typename T> 
vector<T> operator*(vector<T> a, vector<T> b) {
    int N = max(a.size(), b.size()), n = min(a.size(), b.size());
    vector<T> c(N, 0);
    for(int i = 0; i < n; i++) {
        c[i] = a[i] * b[i];
    }
    return c;
}

//拡張ユークリッド
ll ext_gcd(ll a, ll b, ll &x, ll &y) {
    if(b == 0) {
        x = 1, y = 0;
        return a;
    }

    ll q = a/b;
    ll g = ext_gcd(b, a-q*b, x, y);
    ll z = x-q*y;
    x = y, y = z;
    return g;
}
//mod mにおけるaの逆元. aとmは互いに素.
ll inverse(ll a, ll m) {
    ll x, y;
    ext_gcd(a, m, x, y);
    x = (x+m) % m;
    return x;
}
//modint
template<std::uint_fast64_t mod> 
struct modint {
    using u64 = std::uint_fast64_t;
    u64 val;

    modint(u64 v = 0) : val(v % mod) {}

    bool operator==(modint other) {
        return val == other.val;
    }
    bool operator<(const modint& other) const {
        return val < other.val;
    }
    // operator> (大なり)
    bool operator>(const modint& other) const {
        return val > other.val;
    }
    modint operator+(modint other) {
        modint<mod> ans;
        ans.val = val + other.val;
        if(ans.val >= mod) ans.val -= mod;
        return ans;
    }
    modint operator-(modint other) {
        modint<mod> ans;
        if(val < other.val) val += mod;
        ans.val = val - other.val;
        return ans;
    }
    modint operator*(modint other) {
        modint<mod> ans;
        ans.val = (val * other.val) % mod;
        return ans;
    }
    modint operator/(modint other) {
        modint<mod> ans;
        ans.val = (val * inverse(other.val, mod)) % mod;
        return ans;
    }
    modint &operator+=(modint other) {
        *this = *this + other;
        return *this;
    }
    modint &operator-=(modint other) {
        *this = *this - other;
        return *this;
    }
    modint &operator*=(modint other) {
        *this = *this * other;
        return *this;
    }
    modint &operator/=(modint other) {
        *this = *this / other;
        return *this;
    }
    modint &operator++() {
        *this += 1;
        return *this;
    }
    modint &operator++(int) {
        ++(*this);
        return *this;
    }
    modint &operator--() {
        *this -= 1;
        return *this;
    }
    modint &operator--(int) {
        --(*this);
        return *this;
    }
};
//modintの入出力
template<std::uint_fast64_t mod> 
std::ostream& operator<<(std::ostream &os, const modint<mod> &x) {
    // modint の 'val' メンバを出力ストリーム(os)に渡す
    os << x.val;
    return os; // ストリームを返す (チェーンのため)
}
template<std::uint_fast64_t mod> 
std::istream& operator>>(std::istream& is, modint<mod> &x) {
    // modintが内部で使っているu64型を取得
    using u64 = typename modint<mod>::u64; 
    
    u64 input_value;
    is >> input_value; // (1) istream(cin) から一時変数に値を読み込む
    
    // (2) 読み込んだ値を使って modint を再構築する
    //     modintのコンストラクタが (input_value % mod) を処理してくれる
    x = modint<mod>(input_value); 
    
    return is; // (3) ストリームを返す (チェーンのため)
}
//累乗, x^n
template<typename T> 
T pow(T x, int n) {
    T ans = 1;
    while(n > 0) {
        if(n & 1) ans *= x;
        x *= x;
        n >>= 1; 
    }
    return ans;
}
//階乗, n!
template<typename T> 
T fact(T n) {
    if(n == 0) return 1;
    return n * fact(n-1);
}
//nPk
template<typename T> 
T perm(T n, T k) {
    if(k == 0) return 1;
    return n * perm(n-1, k-1);
}
//nCk
template<typename T> 
T comb(T n, T k) {
    if(k > n) return 0;
    return perm(n, min(k, n-k))/fact(min(k, n-k));
}
//ord(n)
ll ord(ll n, ll p) {
    int ans = 0;
    while(n % p == 0) {
        n /= p;
        ans++;
    }
    return ans;
}
//ルジャンドルの公式ord(n!)
ll factord(ll n, ll p) {
    ll ans = 0;
    ll q = p, tmp = n;
    while(tmp > 0) {
        tmp = n/q;
        ans += tmp;
        q *= p;
    }
    return ans;
}
//素因数分解, O(√N)
vector<pair<ll,ll>> factorize(ll N) {
    vector<pair<ll,ll>> ans;
    for(ll p = 2; p*p <= N; p++) {
        int ex = 0;
        while(N % p == 0) {
            N /= p;
            ex++;
        }
        if(ex != 0) ans.push_back({p,ex});
    }
    if(N != 1) ans.push_back({N,1});
    return ans;
}
//素数判定
bool isprime(long long x) {
    if(x == 1) return false;
    
    for(long long i = 2; i*i <= x; i++) {
        if(x % i == 0) return false;
    }
    return true;
}
//エラトステネスの篩
struct Eratosthenes {
    vector<bool> prime;
    vector<int> minfactor;
    vector<int> mobius;
    vector<ll> euler;

    //コンストラクタ O(NloglogN)
    Eratosthenes(int N) : prime(N+1, true),
                          minfactor(N+1, -1),
                          mobius(N+1, 1),
                          euler(N+1, 1) {
        prime[0] = false;
        prime[1] = false;
        minfactor[1] = 1;
        REP(i,1,N) euler[i] = i;

        for(int p = 2; p <= N; p++) {
            if(!prime[p]) continue;

            minfactor[p] = p;
            mobius[p] = -1;
            euler[p] = p-1;

            for(int q = 2; p*q <= N; q++) {
                prime[p*q] = false;
                if(minfactor[p*q] == -1) minfactor[p*q] = p;
                if(q % p == 0) mobius[p*q] = 0;
                else mobius[p*q] *= -1;
                euler[p*q] = euler[p*q]*(p-1)/p;
            }
        }
    }

    //素因数分解 O(logn)
    vector<pair<int,int>> factorize(int n) {
        vector<pair<int,int>> ans;
        while(n > 1) {
            int p = minfactor[n], exp = 0;
            while(n % p == 0) {
                n /= p;
                exp++;
            }
            ans.push_back({p, exp});
        }
        return ans;
    }
    //約数列挙 O(σ(n))
    vector<int> divisors(int n) {
        vector<int> ans = {1};
        while(n > 1) {
            int p = minfactor[n], d = 1, s = ans.size();
            while(n % p == 0) {
                d *= p;
                for(int i = 0; i < s; i++) {
                    ans.push_back(ans[i]*d);
                }
                n /= p;
            }
        }
        return ans;
    }
    //素数関数 O(n)
    int count(int n) {
        int ans = 0;
        REP(i,2,n) if(prime[i]) ans++;
        return ans;
    }
};
//高速ゼータ変換
template<typename T> 
void fast_zeta(vector<T> &f) {
    int N = f.size()-1;
    Eratosthenes sieve(N);
    for(int p = 2; p < N; p++) {
        if(!sieve.prime[p]) continue;
        
        for(int k = N/p; k >= 1; k--) {
            f[k] += f[k*p];
        }
    }
}
//高速メビウス変換
template<typename T> 
void fast_mobius(vector<T> &F) {
    int N = F.size()-1;
    Eratosthenes sieve(N);
    for(int p = 2; p < N; p++) {
        if(!sieve.prime[p]) continue;

        for(int k = 1; k*p <= N; k++) {
            F[k] -= F[k*p];
        }
    }
}
//添字GCD畳み込み
template<typename T> 
vector<T> gcd_conv(vector<T> &f, vector<T> &g) {
    int N = max(f.size(), g.size());
    vector<T> F(N, 0), G(N, 0), H(N);
    for(int i = 0; i < f.size(); i++) F[i] = f[i];
    for(int i = 0; i < g.size(); i++) G[i] = g[i];
    fast_zeta(F);
    fast_zeta(G);
    
    for(int i = 0; i < N; i++) H[i] = F[i]*G[i];
    fast_mobius(H);
    
    return H;
}

//行列積
template<typename T> 
vector<vector<T>> matrix_product(vector<vector<T>> A, vector<vector<T>> B) {
    int H = A.size(), W = A[0].size(), P = B.size(), Q = B[0].size();
    if(W != P) {
        cout << "matrix_size_error" << "\n";
        return vector<vector<T>>(0);
    }

    vector<vector<T>> C(H, vector<T>(Q, 0));
    rep(i,0,H) rep(j,0,Q) {
        rep(k,0,W) {
            C[i][j] += A[i][k]*B[k][j];
        }
    }
    return C;
}
//行列累乗
template<typename T> 
vector<vector<T>> matrix_pow(vector<vector<T>> A, ll n) {
    int N = A.size();
    vector<vector<T>> ans(N, vector<T>(N, 0));
    rep(i,0,N) ans[i][i] = 1;
    
    while(n > 0) {
        if(n & 1) ans = matrix_product(ans, A);
        A = matrix_product(A, A);
        n >>= 1; 
    }
    return ans;
}

//1+2+...+n = n(n+1)/2
ll tri(ll n) {
    ll x = n*(n+1);
    return x/2;
}

//座標圧縮
template<typename T> 
vector<T> compress(vector<T> &A) {
    vector<T> vals = A;
    sort(vals.begin(), vals.end());
    vals.erase(unique(vals.begin(), vals.end()), vals.end());

    for(int i = 0; i < (int)A.size(); i++) {
        A[i] = lower_bound(vals.begin(), vals.end(), A[i]) - vals.begin();
    }
    return vals;
}
template<typename T>
vector<T> compress2(vector<T> &A1, vector<T> &A2) {
    vector<T> vals;
    int N = A1.size();
    for(int i = 0; i < N; i++) {
        for(T d = 0; d < 2; d++) {
            T a1 = A1[i] + d;
            T a2 = A2[i] + d;
            vals.push_back(a1);
            vals.push_back(a2);
        }
    }
    sort(vals.begin(), vals.end());
    vals.erase(unique(vals.begin(), vals.end()), vals.end());
    
    for(int i = 0; i < N;  i++) {
        A1[i] = lower_bound(vals.begin(), vals.end(), A1[i]) - vals.begin();
        A2[i] = lower_bound(vals.begin(), vals.end(), A2[i]) - vals.begin();
    }
    return vals;
}

//正方形グリッドの右回転, 左回転
void rotate_right(vector<vector<char>> &S) {
    int N = S.size();
    auto T = S;
    rep(i,0,N) rep(j,0,N) {
        T[i][j] = S[N-1-j][i];
    }
    S = T;
}
void rotate_left(vector<vector<char>> &S) {
    int N = S.size();
    auto T = S;
    rep(i,0,N) rep(j,0,N) {
        T[i][j] = S[j][N-1-i];
    }
    S = T;
}

//2点(a,b)と(x,y)の距離
long double dist(pair<long double, long double> a, pair<long double, long double> b) {
    return sqrt((a.first-b.first)*(a.first-b.first) + (a.second-b.second)*(a.second-b.second));
}
long double man(pair<long double, long double> a, pair<long double, long double> b) {
    return abs(a.first-b.first) + abs(a.second-b.second);
}
//内分点
pair<long double, long double> internal_division(pair<long double, long double> a, pair<long double, long double> b, long double p) {
    long double x = a.first + (b.first - a.first) * p;
    long double y = a.second + (b.second - a.second) * p;
    return {x, y};
}

//桁数
int digit(ll N) {
    if(N <= 9) return 1;

    return 1 + digit(N / 10);
}
//A進数文字列NをB進数に変換. A,Bは10以下
string base_change(string N, ll A, ll B) {
    ll X = stoll(N), Y = 0;

    ll i = 1;
    while(X != 0) {
        Y += (X % 10) * i;
        i *= A;
        X /= 10;
    }

    X = Y, Y = 0;
    i = 1;
    while(X != 0) {
        Y += (X % B) * i;
        i *= 10;
        X /= B;
    }

    return to_string(Y);
}
//回文判定
bool palin(string S) {
    rep(i,0,S.size()) {
        if(S[i] != S[S.size()-1-i]) return false;
    }
    return true;
}

//hh:mm:ss to second
int convert_to_time(string S) {
    ll h = 10*(S[0]-'0') + (S[1]-'0');
    ll m = 10*(S[3]-'0') + (S[4]-'0');
    ll s = 10*(S[6]-'0') + (S[7]-'0');
    
    return h*3600+m*60+s;
}

//DFS
void dfs(const Graph &G, int v, vector<bool> &seen) { 
    seen[v] = true;
    
    for (auto next_v : G[v]) { 
        if (!seen[next_v]) {
            dfs(G, next_v, seen);
        }
    }
}
void griddfs(const vector<vector<char>> &G, int x, int y, vector<vector<bool>> &seen) {
    int H = G.size(), W = G[0].size();
    seen[x][y] = true;
    
    for (int i = 0; i < 8; i++) { 
        int nx = x + dx[i], ny = y + dy[i];
        if(nx < 0 or nx >= H or ny < 0 or ny >= W) continue;
        if (!seen[nx][ny] and G[nx][ny] != '#') griddfs(G, nx, ny, seen);
    }
}
//BFS
void bfs(const Graph &G, int v, vector<int> &dist) {
    rep(i,0,dist.size()) dist[i] = inf;
    dist[v] = 0;
    queue<int> q;
    q.push(v);
    while(!q.empty()) {
        int u = q.front();
        q.pop();
        for(auto next_u : G[u]) {
            if(dist[next_u] == inf) {
                dist[next_u] = dist[u] + 1;
                q.push(next_u);
            }
        }
    }
}
void gridbfs(const vector<vector<char>> &G, int x, int y, vector<vector<int>> &dist) {
    int H = G.size(), W = G[0].size();
    dist[x][y] = 0;
    queue<pair<int, int>> q;
    q.push(make_pair(x, y));
    while(!q.empty()) {
        int x = q.front().first, y = q.front().second;
        q.pop();
        for(int i = 0; i < 4; i++) {
            int nx = x + dx[i], ny = y + dy[i];
            if(nx < 0 or nx >= H or ny < 0 or ny >= W) continue;
            if(dist[nx][ny] == inf and G[nx][ny] != '#') {
                dist[nx][ny] = dist[x][y] + 1;
                q.push(make_pair(nx, ny));
            }
        }
    }
}
//ワーシャル・フロイド
vector<vector<ll>> floyd(vector<vector<ll>> G) {
    int N = G.size();
    auto dp = G;
    for (int k = 0; k < N; k++){
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if(dp[i][j] > dp[i][k] + dp[k][j] and dp[i][k] != INF and dp[k][j] != INF) {
                    dp[i][j] = dp[i][k] + dp[k][j];
                }
            }
        }
    }
    return dp;
}
//サイクルがあるか判定
bool cycle(const Graph &G, int v, vector<bool> &seen,  vector<bool> &finished) {
    seen[v] = true;    // 行きがけ時に true になる
    for (auto v2 : G[v]) {
        //if (v2 が逆戻りの場合) continue;  // 無向グラフの場合は必要

        // 頂点 v2 がすでに探索済みの場合はスキップ 
        if (finished[v2]) continue;

        // サイクル検出
        if (seen[v2] && !finished[v2]) return true;

        // 頂点 v2 を再帰的に探索
        if (cycle(G, v2, seen, finished)) return true;
    }
    finished[v] = true;  // 帰りがけ時に true になる
    return false;
}

//Union-Find
struct UnionFind {
    vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2
    vector<ll> cnt;
    
    UnionFind(int N) : par(N),
                       cnt(N, 1) { //最初は全てが根であるとして初期化
        for(int i = 0; i < N; i++) par[i] = i;
    }
    
    int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
        if (par[x] == x) return x;
        return par[x] = root(par[x]);
    }
    
    void unite(int x, int y) { // xとyの木を併合
        int rx = root(x); //xの根をrx
        int ry = root(y); //yの根をry
        if (rx == ry) return; //xとyの根が同じ(=同じ木にある)時はそのまま
        par[rx] = ry; //xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
        cnt[ry] += cnt[rx];
    }
    
    bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
        int rx = root(x);
        int ry = root(y);
        return rx == ry;
    }

    ll num(int x) { //データxと同じ木に属するデータの数を得る
        return cnt[x] = cnt[root(x)];
    }
};
//最小全域木
ll Kruskal(const WeightedGraph &G) {
    int N = G.size();
    return 0;
}
//BIT
struct BIT {
    vector<long long> array;
    const int n;

    BIT(int _n) : array(_n, 0), n(_n) {}

    //a_0 + ... + a_i
    long long sum(int i) {
        long long s = 0;
        while(i >= 0) {
            s += array[i];
            i -= (i+1) & -(i+1);
        }
        return s;
    }
    //a_i + ... + a_j
    long long sum(int i, int j) {
        long long ans_i = sum(i-1);
        long long ans_j = sum(j);
        return ans_j - ans_i;
    }
    //a_i += x
    void add(int i, long long x) {
        while(i < n) {
            array[i] += x;
            i += (i+1) & -(i+1);
        }
    }
};
//セグ木
struct SegTree {
    int n, sz;
    vector<long long> node;
    function<ll(ll, ll)> op = [](ll a, ll b) {return max(a,b);}; //セグ木上の積
    ll e = 0; //セグ木上の積の単位元

    SegTree(int n_) {
        n = 1;
        while(n < n_) n *= 2;
        node.resize(2*n-1, e);
    }
    SegTree(vector<long long> a) {
        sz = a.size();

        n = 1;
        while(n < sz) n *= 2;
        node.resize(2*n-1, e);
        for(int i = 0; i < sz; i++) node[n-1+i] = a[i];
        for(int i = n-2; i >= 0; i--) node[i] = op(node[2*i+1], node[2*i+2]);
    }

    //a_iを取得
    long long get(int i) {
        return node[n-1+i];
    }
    //[a,b)における積
    long long prod(int a, int b, int k = 0, int l = 0, int r = -1) {
        if(r < 0) r = n;
        if(r <= a or b <= l) return e;
        if(a <= l and r <= b) return node[k];
        long long vl = prod(a, b, 2*k+1, l, (l+r)/2);
        long long vr = prod(a, b, 2*k+2, (l+r)/2, r);
        return op(vl, vr);
    }
    void update(int i, long long x) {
        i = n-1+i;
        node[i] = x;
        while(i > 0) {
            i = (i-1)/2;
            node[i] = op(node[2*i+1], node[2*i+2]);
        }
    }
    //[a,b)でa_i >= xなる最大のiを求める
    int maxindex(int a, int b, long long x, int k = 0, int l = 0, int r = -1) {
        if(r < 0) r = n;

        if(node[k] < x or r <= a or b <= l) return a-1;
        else if(k >= n-1) return (k - (n-1));
        else {
            int vr = maxindex(a, b, x, 2*k+2, (l+r)/2, r);
            if(vr != a-1) return vr;
            else return maxindex(a, b, x, 2*k+1, l, (l+r)/2);
        }
    }
    //[a,b)でa_i >= xなる最小のiを求める
    int minindex(int a, int b, long long x, int k = 0, int l = 0, int r = -1) {
        if(r < 0) r = n;

        if(node[k] < x or r <= a or b <= l) return b;
        else if(k >= n-1) return (k - (n-1));
        else {
            int vl = minindex(a, b, x, 2*k+1, l, (l+r)/2);
            if(vl != b) return vl;
            else return minindex(a, b, x, 2*k+2, (l+r)/2, r);
        }
    }
};
//遅延セグ木
struct LazySegTree {
    int n;
    vector<ll> node, lazy;
    const ll ex = 0, //セグ木上の積の単位元
             em = 0; //遅延評価木上の積の単位元
    function<ll(ll, ll)> fx = [](ll x, ll y) {return x+y;}, //セグ木上の積
                         fa = [](ll x, ll a) {return x+a;}, //遅延評価木からセグ木への作用
                         fm = [](ll a, ll b) {return a+b;}, //遅延評価木上の積
                         fp = [](ll a, ll n) {return a*n;}; //区間長の作用への影響

    LazySegTree(int n_) {
        n = 1;
        while(n < n_) n *= 2;
        node.resize(2*n-1, ex);
        lazy.resize(2*n-1, em);
    }
    LazySegTree(vector<ll> a) {
        int sz = a.size();
        
        n = 1;
        while(n < sz) n *= 2;
        node.resize(2*n-1, ex);
        lazy.resize(2*n-1, em);

        for(int i = 0; i < sz; i++) node[n-1+i] = a[i];
        for(int i = n-2; i >= 0; i--) node[i] = fx(node[2*i+1], node[2*i+2]);
    }

    void eval(int k, int len) {
        if(lazy[k] == em) return;

        node[k] = fa(node[k], fp(lazy[k], len));
        if(k < n-1) {
            lazy[2*k+1] = fm(lazy[2*k+1], lazy[k]);
            lazy[2*k+2] = fm(lazy[2*k+2], lazy[k]);
        }
        lazy[k] = em;
    }
    //区間[a,b)を値xに更新
    void update(int a, int b, long long x, int k = 0, int l = 0, int r = -1) {
        if(r < 0) r = n;

        eval(k, r - l);
        if(r <= a or b <= l) return;
        if(a <= l and r <= b) {
            lazy[k] = fm(lazy[k], x);
            eval(k, r - l);
        }else {
            update(a, b, x, 2*k+1, l, (l+r)/2);
            update(a, b, x, 2*k+2, (l+r)/2, r);
            node[k] = fx(node[2*k+1], node[2*k+2]);
        }
    }
    //区間[a,b)の積を取得
    ll prod(int a, int b, int k = 0, int l = 0, int r = -1) {
        if(r < 0) r = n;

        eval(k, r - l);
        if(r <= a or b <= l) return ex;
        if(a <= l and r <= b) return node[k];
        
        ll vl = prod(a, b, 2*k+1, l, (l+r)/2);
        ll vr = prod(a, b, 2*k+2, (l+r)/2, r);
        return fx(vl, vr);
    }
    //[a,b)でa_i >= xなる最大のiを求める
    int maxindex(int a, int b, long long x, int k = 0, int l = 0, int r = -1) {
        if(r < 0) r = n;

        eval(k, r - l);
        if(node[k] < x or r <= a or b <= l) return a-1;
        else if(k >= n-1) return (k - (n-1));
        else {
            int vr = maxindex(a, b, x, 2*k+2, (l+r)/2, r);
            if(vr != a-1) return vr;
            else return maxindex(a, b, x, 2*k+1, l, (l+r)/2);
        }
    }
    //[a,b)でa_i >= xなる最小のiを求める
    int minindex(int a, int b, long long x, int k = 0, int l = 0, int r = -1) {
        if(r < 0) r = n;

        eval(k, r - l);
        if(node[k] < x or r <= a or b <= l) return b;
        else if(k >= n-1) return (k - (n-1));
        else {
            int vl = minindex(a, b, x, 2*k+1, l, (l+r)/2);
            if(vl != b) return vl;
            else return minindex(a, b, x, 2*k+2, (l+r)/2, r);
        }
    }
};
//平方分割
struct Backet {
    vector<ll> array;
    vector<ll> backet;
    int N, M;

    Backet(vector<ll> a) {
        array = a;
        N = a.size(), M = ceil(sqrt(N));
        
        backet.resize((N+M-1)/M);
        for(int i = 0; i < N; i++) {
            backet[i/M] += a[i];
        }
    }
    void add(int i, ll x) {
        array[i] += x;
        backet[i/M] += x;
    }
    //区間[i,j)の和
    ll getsum(int i, int j) {
        int l = i/M + 1, r = j/M;
        ll s = 0;
        if(l > r) {
            rep(k,i,j) s += array[k];
        }else {
            rep(k,i,l*M) s += array[k];
            rep(k,l,r) s += backet[k];
            rep(k,r*M,j) s += array[k];
        }
        return s;
    }
};
//最小共通祖先
struct LCA {
    Graph G;
    int N, LOG_N;
    vector<int> depth;
    vector<vector<int>> par;

    function<void(int)> dfs = [&](int v) {
        for(auto next_v : G[v]) {
            if(depth[next_v] != inf) continue;
            depth[next_v] = depth[v] + 1;
            par[0][next_v] = v;
            dfs(next_v);
        }
        return;
    };

    LCA(Graph &g) {
        G = g;
        N = G.size();
        depth.resize(N, inf);
        depth[0] = 0;
        LOG_N = 0;
        while((1<<LOG_N) < N) LOG_N++;
        par.resize(LOG_N+1, vector<int>(N));
        dfs(0);
        rep(i,1,LOG_N) {
            rep(j,0,N) {
                if(par[i-1][j] == -1) par[i][j] = -1;
                else par[i][j] = par[i-1][par[i-1][j]];
            }
        }
    }

    //頂点uのk代目の祖先
    int ancestor(int u, int k) {
        int g = 0;
        while(k > 0) {
            if(k % 2 == 1) u = par[g][u];
            k /= 2;
            g++;
        }
        return u;
    }
    //頂点u,vの最小共通祖先
    int lca(int u, int v) {
        int d1 = depth[u], d2 = depth[v];
        if(d1 < d2) v = ancestor(v, d2-d1);
        if(d1 > d2) u = ancestor(u, d1-d2);

        if(u == v) return u;
        for(int k = LOG_N; k >= 0; k--) {
            if(par[k][u] != par[k][v]) {
                u = par[k][u];
                v = par[k][v];
            }
        }
        return par[0][u];
    }
    //頂点u,vの距離
    int dist(int u, int v) {
        return depth[u] + depth[v] - 2*depth[lca(u, v)];
    }
};

void solve() {
}

int main() {
    int N, K; ll L, R; cin >> N >> K >> L >> R;
    vll A(N);
    vvll lefthalf(N+1), righthalf(N+1);
    rep(i,0,N) {
        cin >> A[i];
    }

    rep(tmp,0,(1<<(N/2))) {
        bitset<20> s(tmp);
        int k = 0;
        ll sum = 0;
        rep(i,0,20) {
            if(s.test(i)) {
                sum += A[i];
                k++;
            }
        }
        lefthalf[k].push_back(sum);
    }
    rep(i,0,N) sort(all(lefthalf[i]));
    rep(tmp,0,(1<<((N+1)/2))) {
        bitset<20> s(tmp);
        int k = 0;
        ll sum = 0;
        rep(i,0,20) {
            if(s.test(i)) {
                sum += A[i+N/2];
                k++;
            }
        }
        righthalf[k].push_back(sum);
    }
    rep(i,0,N) sort(all(righthalf[i]));

    ll ans = 0;
    REP(k,0,K) {
        for(auto x : lefthalf[k]) {
            auto p = lower_bound(all(righthalf[K-k]), L-x), q = upper_bound(all(righthalf[K-k]), R-x);
            ans += ll(q-p);
        }
    }
    cout << ans << "\n";

    return 0;
}
accuracy: 1
time_ms: 250
memory_kb: 23464
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ld = long double;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vvvi = vector<vector<vector<int>>>;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;
using vvvll = vector<vector<vector<ll>>>;
using vd = vector<double>;
using vvd = vector<vector<double>>;
using vstr = vector<string>;
using vchar = vector<char>;
using vvchar = vector<vector<char>>;
using vb = vector<bool>;
using vvb = vector<vector<bool>>;
using vvvb = vector<vector<vector<bool>>>;
using pii = pair<int,int>;
using pll = pair<long long, long long>;
using Graph = vector<vector<int>>;
using WeightedGraph = vector<vector<pair<int,ll>>>;
const int dx[8] = {1, 0, -1, 0, 1, 1, -1, -1};
const int dy[8] = {0, 1, 0, -1, 1, -1, 1, -1};

#define rep(i, a, b) for(ll i = (ll)a; i < (ll)b; i++)
#define REP(i, a, b) for (ll i = (ll)a; i <= (ll)b; i++)
#define rrep(i, a, b) for(ll i = (ll)b-1; i >= (ll)a; i--)
#define RREP(i, a, b) for(ll i = (ll)b; i >= (ll)a; i--)
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
#define YESNO(flag) cout << (flag ? "Yes" : "No") << "\n"
#define spa " "
#define mint modint<MOD>

const int inf = 1070000000;
const long long INF = 4500000000000000000;
//const long long MOD = 998244353;
const long long MOD = 1000000007;
const double pi = 3.141592653589793238;
const double eps = (1e-10);
const string ABC = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string abc = "abcdefghijklmnopqrstuvwxyz";

template<typename T> 
inline bool chmin(T& a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template<typename T> 
inline bool chmax(T& a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
template<typename S, typename T> 
pair<S, T> operator+(pair<S, T> a, pair<S, T> b) {
    pair<S, T> ans;
    ans.first = a.first + b.first;
    ans.second = a.second + b.second;
    return ans;
} 
template<typename T> 
vector<T> operator+(vector<T> a, vector<T> b) {
    int N = max(a.size(), b.size());
    vector<T> c(N);
    for(int i = 0; i < N; i++) {
        if(i >= a.size()) c[i] = b[i];
        else if(i >= b.size()) c[i] = a[i];
        else c[i] = a[i] + b[i];
    }
    return c;
}
template<typename T> 
vector<T> operator*(vector<T> a, vector<T> b) {
    int N = max(a.size(), b.size()), n = min(a.size(), b.size());
    vector<T> c(N, 0);
    for(int i = 0; i < n; i++) {
        c[i] = a[i] * b[i];
    }
    return c;
}

//拡張ユークリッド
ll ext_gcd(ll a, ll b, ll &x, ll &y) {
    if(b == 0) {
        x = 1, y = 0;
        return a;
    }

    ll q = a/b;
    ll g = ext_gcd(b, a-q*b, x, y);
    ll z = x-q*y;
    x = y, y = z;
    return g;
}
//mod mにおけるaの逆元. aとmは互いに素.
ll inverse(ll a, ll m) {
    ll x, y;
    ext_gcd(a, m, x, y);
    x = (x+m) % m;
    return x;
}
//modint
template<std::uint_fast64_t mod> 
struct modint {
    using u64 = std::uint_fast64_t;
    u64 val;

    modint(u64 v = 0) : val(v % mod) {}

    bool operator==(modint other) {
        return val == other.val;
    }
    bool operator<(const modint& other) const {
        return val < other.val;
    }
    // operator> (大なり)
    bool operator>(const modint& other) const {
        return val > other.val;
    }
    modint operator+(modint other) {
        modint<mod> ans;
        ans.val = val + other.val;
        if(ans.val >= mod) ans.val -= mod;
        return ans;
    }
    modint operator-(modint other) {
        modint<mod> ans;
        if(val < other.val) val += mod;
        ans.val = val - other.val;
        return ans;
    }
    modint operator*(modint other) {
        modint<mod> ans;
        ans.val = (val * other.val) % mod;
        return ans;
    }
    modint operator/(modint other) {
        modint<mod> ans;
        ans.val = (val * inverse(other.val, mod)) % mod;
        return ans;
    }
    modint &operator+=(modint other) {
        *this = *this + other;
        return *this;
    }
    modint &operator-=(modint other) {
        *this = *this - other;
        return *this;
    }
    modint &operator*=(modint other) {
        *this = *this * other;
        return *this;
    }
    modint &operator/=(modint other) {
        *this = *this / other;
        return *this;
    }
    modint &operator++() {
        *this += 1;
        return *this;
    }
    modint &operator++(int) {
        ++(*this);
        return *this;
    }
    modint &operator--() {
        *this -= 1;
        return *this;
    }
    modint &operator--(int) {
        --(*this);
        return *this;
    }
};
//modintの入出力
template<std::uint_fast64_t mod> 
std::ostream& operator<<(std::ostream &os, const modint<mod> &x) {
    // modint の 'val' メンバを出力ストリーム(os)に渡す
    os << x.val;
    return os; // ストリームを返す (チェーンのため)
}
template<std::uint_fast64_t mod> 
std::istream& operator>>(std::istream& is, modint<mod> &x) {
    // modintが内部で使っているu64型を取得
    using u64 = typename modint<mod>::u64; 
    
    u64 input_value;
    is >> input_value; // (1) istream(cin) から一時変数に値を読み込む
    
    // (2) 読み込んだ値を使って modint を再構築する
    //     modintのコンストラクタが (input_value % mod) を処理してくれる
    x = modint<mod>(input_value); 
    
    return is; // (3) ストリームを返す (チェーンのため)
}
//累乗, x^n
template<typename T> 
T pow(T x, int n) {
    T ans = 1;
    while(n > 0) {
        if(n & 1) ans *= x;
        x *= x;
        n >>= 1; 
    }
    return ans;
}
//階乗, n!
template<typename T> 
T fact(T n) {
    if(n == 0) return 1;
    return n * fact(n-1);
}
//nPk
template<typename T> 
T perm(T n, T k) {
    if(k == 0) return 1;
    return n * perm(n-1, k-1);
}
//nCk
template<typename T> 
T comb(T n, T k) {
    if(k > n) return 0;
    return perm(n, min(k, n-k))/fact(min(k, n-k));
}
//ord(n)
ll ord(ll n, ll p) {
    int ans = 0;
    while(n % p == 0) {
        n /= p;
        ans++;
    }
    return ans;
}
//ルジャンドルの公式ord(n!)
ll factord(ll n, ll p) {
    ll ans = 0;
    ll q = p, tmp = n;
    while(tmp > 0) {
        tmp = n/q;
        ans += tmp;
        q *= p;
    }
    return ans;
}
//素因数分解, O(√N)
vector<pair<ll,ll>> factorize(ll N) {
    vector<pair<ll,ll>> ans;
    for(ll p = 2; p*p <= N; p++) {
        int ex = 0;
        while(N % p == 0) {
            N /= p;
            ex++;
        }
        if(ex != 0) ans.push_back({p,ex});
    }
    if(N != 1) ans.push_back({N,1});
    return ans;
}
//素数判定
bool isprime(long long x) {
    if(x == 1) return false;
    
    for(long long i = 2; i*i <= x; i++) {
        if(x % i == 0) return false;
    }
    return true;
}
//エラトステネスの篩
struct Eratosthenes {
    vector<bool> prime;
    vector<int> minfactor;
    vector<int> mobius;
    vector<ll> euler;

    //コンストラクタ O(NloglogN)
    Eratosthenes(int N) : prime(N+1, true),
                          minfactor(N+1, -1),
                          mobius(N+1, 1),
                          euler(N+1, 1) {
        prime[0] = false;
        prime[1] = false;
        minfactor[1] = 1;
        REP(i,1,N) euler[i] = i;

        for(int p = 2; p <= N; p++) {
            if(!prime[p]) continue;

            minfactor[p] = p;
            mobius[p] = -1;
            euler[p] = p-1;

            for(int q = 2; p*q <= N; q++) {
                prime[p*q] = false;
                if(minfactor[p*q] == -1) minfactor[p*q] = p;
                if(q % p == 0) mobius[p*q] = 0;
                else mobius[p*q] *= -1;
                euler[p*q] = euler[p*q]*(p-1)/p;
            }
        }
    }

    //素因数分解 O(logn)
    vector<pair<int,int>> factorize(int n) {
        vector<pair<int,int>> ans;
        while(n > 1) {
            int p = minfactor[n], exp = 0;
            while(n % p == 0) {
                n /= p;
                exp++;
            }
            ans.push_back({p, exp});
        }
        return ans;
    }
    //約数列挙 O(σ(n))
    vector<int> divisors(int n) {
        vector<int> ans = {1};
        while(n > 1) {
            int p = minfactor[n], d = 1, s = ans.size();
            while(n % p == 0) {
                d *= p;
                for(int i = 0; i < s; i++) {
                    ans.push_back(ans[i]*d);
                }
                n /= p;
            }
        }
        return ans;
    }
    //素数関数 O(n)
    int count(int n) {
        int ans = 0;
        REP(i,2,n) if(prime[i]) ans++;
        return ans;
    }
};
//高速ゼータ変換
template<typename T> 
void fast_zeta(vector<T> &f) {
    int N = f.size()-1;
    Eratosthenes sieve(N);
    for(int p = 2; p < N; p++) {
        if(!sieve.prime[p]) continue;
        
        for(int k = N/p; k >= 1; k--) {
            f[k] += f[k*p];
        }
    }
}
//高速メビウス変換
template<typename T> 
void fast_mobius(vector<T> &F) {
    int N = F.size()-1;
    Eratosthenes sieve(N);
    for(int p = 2; p < N; p++) {
        if(!sieve.prime[p]) continue;

        for(int k = 1; k*p <= N; k++) {
            F[k] -= F[k*p];
        }
    }
}
//添字GCD畳み込み
template<typename T> 
vector<T> gcd_conv(vector<T> &f, vector<T> &g) {
    int N = max(f.size(), g.size());
    vector<T> F(N, 0), G(N, 0), H(N);
    for(int i = 0; i < f.size(); i++) F[i] = f[i];
    for(int i = 0; i < g.size(); i++) G[i] = g[i];
    fast_zeta(F);
    fast_zeta(G);
    
    for(int i = 0; i < N; i++) H[i] = F[i]*G[i];
    fast_mobius(H);
    
    return H;
}

//行列積
template<typename T> 
vector<vector<T>> matrix_product(vector<vector<T>> A, vector<vector<T>> B) {
    int H = A.size(), W = A[0].size(), P = B.size(), Q = B[0].size();
    if(W != P) {
        cout << "matrix_size_error" << "\n";
        return vector<vector<T>>(0);
    }

    vector<vector<T>> C(H, vector<T>(Q, 0));
    rep(i,0,H) rep(j,0,Q) {
        rep(k,0,W) {
            C[i][j] += A[i][k]*B[k][j];
        }
    }
    return C;
}
//行列累乗
template<typename T> 
vector<vector<T>> matrix_pow(vector<vector<T>> A, ll n) {
    int N = A.size();
    vector<vector<T>> ans(N, vector<T>(N, 0));
    rep(i,0,N) ans[i][i] = 1;
    
    while(n > 0) {
        if(n & 1) ans = matrix_product(ans, A);
        A = matrix_product(A, A);
        n >>= 1; 
    }
    return ans;
}

//1+2+...+n = n(n+1)/2
ll tri(ll n) {
    ll x = n*(n+1);
    return x/2;
}

//座標圧縮
template<typename T> 
vector<T> compress(vector<T> &A) {
    vector<T> vals = A;
    sort(vals.begin(), vals.end());
    vals.erase(unique(vals.begin(), vals.end()), vals.end());

    for(int i = 0; i < (int)A.size(); i++) {
        A[i] = lower_bound(vals.begin(), vals.end(), A[i]) - vals.begin();
    }
    return vals;
}
template<typename T>
vector<T> compress2(vector<T> &A1, vector<T> &A2) {
    vector<T> vals;
    int N = A1.size();
    for(int i = 0; i < N; i++) {
        for(T d = 0; d < 2; d++) {
            T a1 = A1[i] + d;
            T a2 = A2[i] + d;
            vals.push_back(a1);
            vals.push_back(a2);
        }
    }
    sort(vals.begin(), vals.end());
    vals.erase(unique(vals.begin(), vals.end()), vals.end());
    
    for(int i = 0; i < N;  i++) {
        A1[i] = lower_bound(vals.begin(), vals.end(), A1[i]) - vals.begin();
        A2[i] = lower_bound(vals.begin(), vals.end(), A2[i]) - vals.begin();
    }
    return vals;
}

//正方形グリッドの右回転, 左回転
void rotate_right(vector<vector<char>> &S) {
    int N = S.size();
    auto T = S;
    rep(i,0,N) rep(j,0,N) {
        T[i][j] = S[N-1-j][i];
    }
    S = T;
}
void rotate_left(vector<vector<char>> &S) {
    int N = S.size();
    auto T = S;
    rep(i,0,N) rep(j,0,N) {
        T[i][j] = S[j][N-1-i];
    }
    S = T;
}

//2点(a,b)と(x,y)の距離
long double dist(pair<long double, long double> a, pair<long double, long double> b) {
    return sqrt((a.first-b.first)*(a.first-b.first) + (a.second-b.second)*(a.second-b.second));
}
long double man(pair<long double, long double> a, pair<long double, long double> b) {
    return abs(a.first-b.first) + abs(a.second-b.second);
}
//内分点
pair<long double, long double> internal_division(pair<long double, long double> a, pair<long double, long double> b, long double p) {
    long double x = a.first + (b.first - a.first) * p;
    long double y = a.second + (b.second - a.second) * p;
    return {x, y};
}

//桁数
int digit(ll N) {
    if(N <= 9) return 1;

    return 1 + digit(N / 10);
}
//A進数文字列NをB進数に変換. A,Bは10以下
string base_change(string N, ll A, ll B) {
    ll X = stoll(N), Y = 0;

    ll i = 1;
    while(X != 0) {
        Y += (X % 10) * i;
        i *= A;
        X /= 10;
    }

    X = Y, Y = 0;
    i = 1;
    while(X != 0) {
        Y += (X % B) * i;
        i *= 10;
        X /= B;
    }

    return to_string(Y);
}
//回文判定
bool palin(string S) {
    rep(i,0,S.size()) {
        if(S[i] != S[S.size()-1-i]) return false;
    }
    return true;
}

//hh:mm:ss to second
int convert_to_time(string S) {
    ll h = 10*(S[0]-'0') + (S[1]-'0');
    ll m = 10*(S[3]-'0') + (S[4]-'0');
    ll s = 10*(S[6]-'0') + (S[7]-'0');
    
    return h*3600+m*60+s;
}

//DFS
void dfs(const Graph &G, int v, vector<bool> &seen) { 
    seen[v] = true;
    
    for (auto next_v : G[v]) { 
        if (!seen[next_v]) {
            dfs(G, next_v, seen);
        }
    }
}
void griddfs(const vector<vector<char>> &G, int x, int y, vector<vector<bool>> &seen) {
    int H = G.size(), W = G[0].size();
    seen[x][y] = true;
    
    for (int i = 0; i < 8; i++) { 
        int nx = x + dx[i], ny = y + dy[i];
        if(nx < 0 or nx >= H or ny < 0 or ny >= W) continue;
        if (!seen[nx][ny] and G[nx][ny] != '#') griddfs(G, nx, ny, seen);
    }
}
//BFS
void bfs(const Graph &G, int v, vector<int> &dist) {
    rep(i,0,dist.size()) dist[i] = inf;
    dist[v] = 0;
    queue<int> q;
    q.push(v);
    while(!q.empty()) {
        int u = q.front();
        q.pop();
        for(auto next_u : G[u]) {
            if(dist[next_u] == inf) {
                dist[next_u] = dist[u] + 1;
                q.push(next_u);
            }
        }
    }
}
void gridbfs(const vector<vector<char>> &G, int x, int y, vector<vector<int>> &dist) {
    int H = G.size(), W = G[0].size();
    dist[x][y] = 0;
    queue<pair<int, int>> q;
    q.push(make_pair(x, y));
    while(!q.empty()) {
        int x = q.front().first, y = q.front().second;
        q.pop();
        for(int i = 0; i < 4; i++) {
            int nx = x + dx[i], ny = y + dy[i];
            if(nx < 0 or nx >= H or ny < 0 or ny >= W) continue;
            if(dist[nx][ny] == inf and G[nx][ny] != '#') {
                dist[nx][ny] = dist[x][y] + 1;
                q.push(make_pair(nx, ny));
            }
        }
    }
}
//ワーシャル・フロイド
vector<vector<ll>> floyd(vector<vector<ll>> G) {
    int N = G.size();
    auto dp = G;
    for (int k = 0; k < N; k++){
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if(dp[i][j] > dp[i][k] + dp[k][j] and dp[i][k] != INF and dp[k][j] != INF) {
                    dp[i][j] = dp[i][k] + dp[k][j];
                }
            }
        }
    }
    return dp;
}
//サイクルがあるか判定
bool cycle(const Graph &G, int v, vector<bool> &seen,  vector<bool> &finished) {
    seen[v] = true;    // 行きがけ時に true になる
    for (auto v2 : G[v]) {
        //if (v2 が逆戻りの場合) continue;  // 無向グラフの場合は必要

        // 頂点 v2 がすでに探索済みの場合はスキップ 
        if (finished[v2]) continue;

        // サイクル検出
        if (seen[v2] && !finished[v2]) return true;

        // 頂点 v2 を再帰的に探索
        if (cycle(G, v2, seen, finished)) return true;
    }
    finished[v] = true;  // 帰りがけ時に true になる
    return false;
}

//Union-Find
struct UnionFind {
    vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2
    vector<ll> cnt;
    
    UnionFind(int N) : par(N),
                       cnt(N, 1) { //最初は全てが根であるとして初期化
        for(int i = 0; i < N; i++) par[i] = i;
    }
    
    int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
        if (par[x] == x) return x;
        return par[x] = root(par[x]);
    }
    
    void unite(int x, int y) { // xとyの木を併合
        int rx = root(x); //xの根をrx
        int ry = root(y); //yの根をry
        if (rx == ry) return; //xとyの根が同じ(=同じ木にある)時はそのまま
        par[rx] = ry; //xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
        cnt[ry] += cnt[rx];
    }
    
    bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
        int rx = root(x);
        int ry = root(y);
        return rx == ry;
    }

    ll num(int x) { //データxと同じ木に属するデータの数を得る
        return cnt[x] = cnt[root(x)];
    }
};
//最小全域木
ll Kruskal(const WeightedGraph &G) {
    int N = G.size();
    return 0;
}
//BIT
struct BIT {
    vector<long long> array;
    const int n;

    BIT(int _n) : array(_n, 0), n(_n) {}

    //a_0 + ... + a_i
    long long sum(int i) {
        long long s = 0;
        while(i >= 0) {
            s += array[i];
            i -= (i+1) & -(i+1);
        }
        return s;
    }
    //a_i + ... + a_j
    long long sum(int i, int j) {
        long long ans_i = sum(i-1);
        long long ans_j = sum(j);
        return ans_j - ans_i;
    }
    //a_i += x
    void add(int i, long long x) {
        while(i < n) {
            array[i] += x;
            i += (i+1) & -(i+1);
        }
    }
};
//セグ木
struct SegTree {
    int n, sz;
    vector<long long> node;
    function<ll(ll, ll)> op = [](ll a, ll b) {return max(a,b);}; //セグ木上の積
    ll e = 0; //セグ木上の積の単位元

    SegTree(int n_) {
        n = 1;
        while(n < n_) n *= 2;
        node.resize(2*n-1, e);
    }
    SegTree(vector<long long> a) {
        sz = a.size();

        n = 1;
        while(n < sz) n *= 2;
        node.resize(2*n-1, e);
        for(int i = 0; i < sz; i++) node[n-1+i] = a[i];
        for(int i = n-2; i >= 0; i--) node[i] = op(node[2*i+1], node[2*i+2]);
    }

    //a_iを取得
    long long get(int i) {
        return node[n-1+i];
    }
    //[a,b)における積
    long long prod(int a, int b, int k = 0, int l = 0, int r = -1) {
        if(r < 0) r = n;
        if(r <= a or b <= l) return e;
        if(a <= l and r <= b) return node[k];
        long long vl = prod(a, b, 2*k+1, l, (l+r)/2);
        long long vr = prod(a, b, 2*k+2, (l+r)/2, r);
        return op(vl, vr);
    }
    void update(int i, long long x) {
        i = n-1+i;
        node[i] = x;
        while(i > 0) {
            i = (i-1)/2;
            node[i] = op(node[2*i+1], node[2*i+2]);
        }
    }
    //[a,b)でa_i >= xなる最大のiを求める
    int maxindex(int a, int b, long long x, int k = 0, int l = 0, int r = -1) {
        if(r < 0) r = n;

        if(node[k] < x or r <= a or b <= l) return a-1;
        else if(k >= n-1) return (k - (n-1));
        else {
            int vr = maxindex(a, b, x, 2*k+2, (l+r)/2, r);
            if(vr != a-1) return vr;
            else return maxindex(a, b, x, 2*k+1, l, (l+r)/2);
        }
    }
    //[a,b)でa_i >= xなる最小のiを求める
    int minindex(int a, int b, long long x, int k = 0, int l = 0, int r = -1) {
        if(r < 0) r = n;

        if(node[k] < x or r <= a or b <= l) return b;
        else if(k >= n-1) return (k - (n-1));
        else {
            int vl = minindex(a, b, x, 2*k+1, l, (l+r)/2);
            if(vl != b) return vl;
            else return minindex(a, b, x, 2*k+2, (l+r)/2, r);
        }
    }
};
//遅延セグ木
struct LazySegTree {
    int n;
    vector<ll> node, lazy;
    const ll ex = 0, //セグ木上の積の単位元
             em = 0; //遅延評価木上の積の単位元
    function<ll(ll, ll)> fx = [](ll x, ll y) {return x+y;}, //セグ木上の積
                         fa = [](ll x, ll a) {return x+a;}, //遅延評価木からセグ木への作用
                         fm = [](ll a, ll b) {return a+b;}, //遅延評価木上の積
                         fp = [](ll a, ll n) {return a*n;}; //区間長の作用への影響

    LazySegTree(int n_) {
        n = 1;
        while(n < n_) n *= 2;
        node.resize(2*n-1, ex);
        lazy.resize(2*n-1, em);
    }
    LazySegTree(vector<ll> a) {
        int sz = a.size();
        
        n = 1;
        while(n < sz) n *= 2;
        node.resize(2*n-1, ex);
        lazy.resize(2*n-1, em);

        for(int i = 0; i < sz; i++) node[n-1+i] = a[i];
        for(int i = n-2; i >= 0; i--) node[i] = fx(node[2*i+1], node[2*i+2]);
    }

    void eval(int k, int len) {
        if(lazy[k] == em) return;

        node[k] = fa(node[k], fp(lazy[k], len));
        if(k < n-1) {
            lazy[2*k+1] = fm(lazy[2*k+1], lazy[k]);
            lazy[2*k+2] = fm(lazy[2*k+2], lazy[k]);
        }
        lazy[k] = em;
    }
    //区間[a,b)を値xに更新
    void update(int a, int b, long long x, int k = 0, int l = 0, int r = -1) {
        if(r < 0) r = n;

        eval(k, r - l);
        if(r <= a or b <= l) return;
        if(a <= l and r <= b) {
            lazy[k] = fm(lazy[k], x);
            eval(k, r - l);
        }else {
            update(a, b, x, 2*k+1, l, (l+r)/2);
            update(a, b, x, 2*k+2, (l+r)/2, r);
            node[k] = fx(node[2*k+1], node[2*k+2]);
        }
    }
    //区間[a,b)の積を取得
    ll prod(int a, int b, int k = 0, int l = 0, int r = -1) {
        if(r < 0) r = n;

        eval(k, r - l);
        if(r <= a or b <= l) return ex;
        if(a <= l and r <= b) return node[k];
        
        ll vl = prod(a, b, 2*k+1, l, (l+r)/2);
        ll vr = prod(a, b, 2*k+2, (l+r)/2, r);
        return fx(vl, vr);
    }
    //[a,b)でa_i >= xなる最大のiを求める
    int maxindex(int a, int b, long long x, int k = 0, int l = 0, int r = -1) {
        if(r < 0) r = n;

        eval(k, r - l);
        if(node[k] < x or r <= a or b <= l) return a-1;
        else if(k >= n-1) return (k - (n-1));
        else {
            int vr = maxindex(a, b, x, 2*k+2, (l+r)/2, r);
            if(vr != a-1) return vr;
            else return maxindex(a, b, x, 2*k+1, l, (l+r)/2);
        }
    }
    //[a,b)でa_i >= xなる最小のiを求める
    int minindex(int a, int b, long long x, int k = 0, int l = 0, int r = -1) {
        if(r < 0) r = n;

        eval(k, r - l);
        if(node[k] < x or r <= a or b <= l) return b;
        else if(k >= n-1) return (k - (n-1));
        else {
            int vl = minindex(a, b, x, 2*k+1, l, (l+r)/2);
            if(vl != b) return vl;
            else return minindex(a, b, x, 2*k+2, (l+r)/2, r);
        }
    }
};
//平方分割
struct Backet {
    vector<ll> array;
    vector<ll> backet;
    int N, M;

    Backet(vector<ll> a) {
        array = a;
        N = a.size(), M = ceil(sqrt(N));
        
        backet.resize((N+M-1)/M);
        for(int i = 0; i < N; i++) {
            backet[i/M] += a[i];
        }
    }
    void add(int i, ll x) {
        array[i] += x;
        backet[i/M] += x;
    }
    //区間[i,j)の和
    ll getsum(int i, int j) {
        int l = i/M + 1, r = j/M;
        ll s = 0;
        if(l > r) {
            rep(k,i,j) s += array[k];
        }else {
            rep(k,i,l*M) s += array[k];
            rep(k,l,r) s += backet[k];
            rep(k,r*M,j) s += array[k];
        }
        return s;
    }
};
//最小共通祖先
struct LCA {
    Graph G;
    int N, LOG_N;
    vector<int> depth;
    vector<vector<int>> par;

    function<void(int)> dfs = [&](int v) {
        for(auto next_v : G[v]) {
            if(depth[next_v] != inf) continue;
            depth[next_v] = depth[v] + 1;
            par[0][next_v] = v;
            dfs(next_v);
        }
        return;
    };

    LCA(Graph &g) {
        G = g;
        N = G.size();
        depth.resize(N, inf);
        depth[0] = 0;
        LOG_N = 0;
        while((1<<LOG_N) < N) LOG_N++;
        par.resize(LOG_N+1, vector<int>(N));
        dfs(0);
        rep(i,1,LOG_N) {
            rep(j,0,N) {
                if(par[i-1][j] == -1) par[i][j] = -1;
                else par[i][j] = par[i-1][par[i-1][j]];
            }
        }
    }

    //頂点uのk代目の祖先
    int ancestor(int u, int k) {
        int g = 0;
        while(k > 0) {
            if(k % 2 == 1) u = par[g][u];
            k /= 2;
            g++;
        }
        return u;
    }
    //頂点u,vの最小共通祖先
    int lca(int u, int v) {
        int d1 = depth[u], d2 = depth[v];
        if(d1 < d2) v = ancestor(v, d2-d1);
        if(d1 > d2) u = ancestor(u, d1-d2);

        if(u == v) return u;
        for(int k = LOG_N; k >= 0; k--) {
            if(par[k][u] != par[k][v]) {
                u = par[k][u];
                v = par[k][v];
            }
        }
        return par[0][u];
    }
    //頂点u,vの距離
    int dist(int u, int v) {
        return depth[u] + depth[v] - 2*depth[lca(u, v)];
    }
};

void solve() {
}

int main() {
    int N, K; ll L, R; cin >> N >> K >> L >> R;
    vll A(N);
    vvll lefthalf(N+1), righthalf(N+1);
    rep(i,0,N) {
        cin >> A[i];
    }

    rep(tmp,0,(1<<(N/2))) {
        bitset<20> s(tmp);
        int k = 0;
        ll sum = 0;
        rep(i,0,20) {
            if(s.test(i)) {
                sum += A[i];
                k++;
            }
        }
        lefthalf[k].push_back(sum);
    }
    rep(i,0,N) sort(all(lefthalf[i]));
    rep(tmp,0,(1<<((N+1)/2))) {
        bitset<20> s(tmp);
        int k = 0;
        ll sum = 0;
        rep(i,0,20) {
            if(s.test(i)) {
                sum += A[i+N/2];
                k++;
            }
        }
        righthalf[k].push_back(sum);
    }
    rep(i,0,N) sort(all(righthalf[i]));

    int ans = 0;
    REP(k,0,K) {
        for(auto x : lefthalf[k]) {
            auto p = lower_bound(all(righthalf[K-k]), L-x), q = upper_bound(all(righthalf[K-k]), R-x);
            ans += q-p;
        }
    }
    cout << ans << "\n";

    return 0;
}
accuracy: 0.5
time_ms: 30
memory_kb: 6796
final_rank: 20

code_snippet: #include <bits/stdc++.h>

using namespace std;
using ll = long long;
#define rep(i, n) for (int i = 0; i < (n); ++i)

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    ll N, K, L, R;
    cin >> N >> K >> L >> R;
    vector<ll> A(N);
    rep(i, N) cin >> A[i];

    int M = N / 2;
    vector<vector<ll>> sum1(M + 1);
    rep(i, (1 << M)) {
        ll sum = 0;
        int cnt = 0;
        rep(j, M) {
            if ((i >> j) & 1) {
                sum += A[j];
                cnt++;
            }
        }
        sum1[cnt].push_back(sum);
    }

    vector<vector<ll>> sum2(N - M + 1);
    rep(i, (1 << (N - M))) {
        ll sum = 0;
        int cnt = 0;
        rep(j, N - M) {
            if ((i >> j) & 1) {
                sum += A[j + M];
                cnt++;
            }
        }
        sum2[cnt].push_back(sum);
    }

    rep(i, sum2.size()) { sort(sum2[i].begin(), sum2[i].end()); }

    ll res = 0;
    rep(i, sum1.size()) {
        int remain_cnt = K - i;
        if (remain_cnt >= sum2.size()) continue;
        for (ll s1 : sum1[i]) {
            auto& vec = sum2[remain_cnt];
            auto r = upper_bound(vec.begin(), vec.end(), R - s1);
            auto l = lower_bound(vec.begin(), vec.end(), L - s1);
            ll cnt = r - l;
            res += cnt;
        }
    }

    cout << res << endl;
    return 0;
}
accuracy: 1
time_ms: 280
memory_kb: 23044
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll=long long;

int main(){
    ll N,K,L,R; cin>>N>>K>>L>>R;
    vector<ll> A(N);
    for(ll i=0;i<N;i++) cin>>A[i];

    ll N1=N/2,N2=N-N1;
    vector<vector<ll>> A1(N1+1),A2(N2+1);
    for(int i=0;i<(1<<N1);i++){
        ll popcount=0,value=0;
        for(int j=0;j<N1;j++){
            if((i&1<<j)!=0){
                popcount++;
                value+=A[j];
            }
        }
        A1[popcount].push_back(value);
    }
    for(int i=0;i<(1<<N2);i++){
        ll popcount=0,value=0;
        for(int j=0;j<N2;j++){
            if((i&1<<j)!=0){
                popcount++;
                value+=A[N1+j];
            }
        }
        A2[popcount].push_back(value);
    }
    for(int i=0;i<=N2;i++) sort(A2[i].begin(),A2[i].end());

    ll ans=0;
    for(int i=0;i<=N1;i++){
        if(K-i<0||N2<K-i) continue;
        for(int j=0;j<A1[i].size();j++){
            ans+=upper_bound(A2[K-i].begin(),A2[K-i].end(),R-A1[i][j])-lower_bound(A2[K-i].begin(),A2[K-i].end(),L-A1[i][j]);
        }
    }
    cout<<ans<<endl;
}
accuracy: 1
time_ms: 270
memory_kb: 23808
final_rank: 7

code_snippet: #include <bits/stdc++.h>

using namespace std;

void generate_sums_bitmask(int s, int e, const vector<long long> &a, vector<vector<long long>> &sums) {
  //sからe-1まで。
  int n = e - s;
  for (int i = 0; i < (1 << n); ++i) {
    long long curr_sum = 0;
    int count = 0;
    for (int j = 0; j < n; ++j) {
      if ((i >> j) & 1) {
        curr_sum += a[s + j];
        count++;
      }
    }
    sums[count].push_back(curr_sum);
  }
}

int main() {
  int N, K;
  long long L, R;
  cin >> N >> K >> L >> R;

  // N枚のコインの値段 a_i を入力
  vector<long long> a(N);
  for (int i = 0; i < N; ++i) {
      cin >> a[i];
  }

  int n1 = N / 2;
  int n2 = N - n1;
  vector<vector<long long>> sum1(n1 + 1);
  generate_sums_bitmask(0, n1, a, sum1);
  vector<vector<long long>> sum2(n2 + 1);
  generate_sums_bitmask(n1, N, a, sum2);

  for (auto & v: sum2) {
    sort(v.begin(), v.end());
  }
  long long ans = 0;
  for (int i = 0; i <= n1; ++i) {
    int j = K - i;
    if (j < 0 || j > n2) continue;
    for (long long s1: sum1[i]) {
      long long l = L - s1;
      long long r = R - s1;
      auto it_l = lower_bound(sum2[j].begin(), sum2[j].end(), l);
      auto it_r = upper_bound(sum2[j].begin(), sum2[j].end(), r);
      ans += it_r - it_l;
    }
  }

  cout << ans << endl;
  return 0;

}
accuracy: 1
time_ms: 280
memory_kb: 23432
final_rank: 11

code_snippet: #include <bits/stdc++.h>

using namespace std;

void generate_sums_bitmask(int s, int e, const vector<long long> &a, vector<vector<long long>> &sums) {
  //sからe-1まで。
  int n = e - s;
  for (int i = 0; i < (1 << n); ++i) {
    long long curr_sum = 0;
    int count = 0;
    for (int j = 0; j < n; ++j) {
      if ((i >> j) & 1) {
        curr_sum += a[s + j];
        count++;
      }
    }
    sums[count].push_back(curr_sum);
  }
}

int main() {
  int N, K;
  long long L, R;
  cin >> N >> K >> L >> R;

  // N枚のコインの値段 a_i を入力
  vector<long long> a(N);
  for (int i = 0; i < N; ++i) {
      cin >> a[i];
  }

  int n1 = N / 2;
  int n2 = N - n1;
  vector<vector<long long>> sum1(n1 + 1);
  generate_sums_bitmask(0, n1, a, sum1);
  vector<vector<long long>> sum2(n2 + 1);
  generate_sums_bitmask(n1, N, a, sum2);

  for (auto & v: sum2) {
    sort(v.begin(), v.end());
  }
  long long ans = 0;
  for (int i = 0; i <= n1; ++i) {
    int j = K - i;
    if (j < 0 || j > n2) continue;
    for (long long s1: sum1[i]) {
      long long l = L - s1;
      long long r = R - s1;
      auto it_l = lower_bound(sum2[j].begin(), sum2[j].end(), l);
      auto it_r = upper_bound(sum2[j].begin(), sum2[j].end(), r);
      ans += distance(it_l, it_r);
    }
  }

  cout << ans << endl;
  return 0;

}
accuracy: 1
time_ms: 280
memory_kb: 23432
final_rank: 11

code_snippet: #include<bits/stdc++.h>

using namespace std;

typedef long long ll;

int N,K;
ll a[50];
ll L,R;

vector<pair<int,ll> >x,y;

void func(int l,int r ,vector<pair<int,ll> >&t){
    int w=r-l;
    for(int i=0;i<(1<<w);i++){
        ll sum=0;
        int cnt=0;
        for(int j=0;j<w;j++){
            if((i>>j)&1){
                sum+=a[l+j];
                cnt++;
            }
        }
        t.push_back(make_pair(cnt,sum));
    }
}

int main(){
    cin>>N>>K>>L>>R;
    for(int i=0;i<N;i++)
        cin>>a[i];
    func(0,N/2,x);
    func(N/2,N,y);
    sort(y.begin(),y.end());
    ll ans=0;
    for(int i=0;i<x.size();i++){
        vector<pair<int,ll> >::iterator it1,it2;
        it1=lower_bound(y.begin(),y.end(),pair<int,ll>(K-x[i].first,L-x[i].second));
        it2=upper_bound(y.begin(),y.end(),pair<int,ll>(K-x[i].first,R-x[i].second));
        ans+=(it2-it1);
    }
    cout<<ans<<endl;
    return 0;
}
accuracy: 1
time_ms: 510
memory_kb: 45680
final_rank: 16

code_snippet: #include <bits/stdc++.h>
#define ll long long
using namespace std;
int n,k;
ll l,r;
ll a[44];
vector<ll> b[41];// 选i个硬币有哪些不同结果 
vector<ll> c[41];
void dfs1(int i,ll v,int cnt){
	if(i==n/2){b[cnt].push_back(v);return;}
	dfs1(i+1,v+a[i],cnt+1);
	dfs1(i+1,v,cnt);
}
void dfs2(int i,ll v,int cnt){
	if(i==n){c[cnt].push_back(v);return;}
	dfs2(i+1,v+a[i],cnt+1);
	dfs2(i+1,v,cnt);
}
void solve(){
	if(n==1){cout<<(k==1&&a[0]>=l&&a[0]<=r)<<"\n";return;}
	dfs1(0,0,0);
	dfs2(n/2,0,0);
	ll res=0;
	for(int i=0;i<=40;i++)sort(b[i].begin(),b[i].end()),sort(c[i].begin(),c[i].end());
	for(int i=0;i<=k;i++){
		int j=k-i;
		for(int t=0;t<b[i].size();t++){
			ll v=b[i][t];
			res+=upper_bound(c[j].begin(),c[j].end(),r-v)-lower_bound(c[j].begin(),c[j].end(),l-v);
		}
	}cout<<res<<"\n";
}
int main(){
	cin>>n>>k>>l>>r;
	for(int i=0;i<n;i++)cin>>a[i];
	solve();
	return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 23308
final_rank: 2

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<cmath>
#include<iomanip>
#include<map>
#include<stack>
#include<queue>
#include<set>
#include<deque>
#include<list>
#include<bitset>
using namespace std;
using ll = long long;
using ld = long double;
using P = pair<ll,ll>;

const ld EPS = 1e-10;
const ll MOD = 1000000007LL;
const ll INF = 1LL << 60;
const ld PI = acos( -1.0 );

#define SWAP( A, B ) { auto tmp = A; A = B; B = tmp; }

template <typename T>
void print( vector<T> v ){
    if( v.size() == 0 ) return;
    for( int i = 0 ; i < v.size() - 1 ; i++ )
        cout << v[i] << ' ';
    cout << v[v.size()-1] << endl;
}

int main(){

    int K, N;
    ll a, L, R, res = 0;
    vector<ll> la, ra;
    vector<vector<ll>> lax, rax;

    cin >> N >> K >> L >> R;
    for( int i = 0 ; i < N / 2 ; i++ ){
        cin >> a;
        la.push_back( a );
        vector<ll> v;
        lax.push_back( v );
    }
    for( int i = N / 2 ; i < N ; i++ ){
        cin >> a;
        ra.push_back( a );
        vector<ll> v;
        rax.push_back( v );
    }
    vector<ll> tmp;
    lax.push_back( tmp );
    rax.push_back( tmp );
    for( ll i = 0 ; i < ( 1 << la.size() ) ; i++ ){
        int id = 0;
        ll _i = i, val = 0;
        for( int j = 0 ; j < la.size() ; j++ ){
            if( _i & 1LL ){
                id++;
                val += la[j];
            }
            _i >>= 1;
        }
        lax[id].push_back( val );
    }
    for( ll i = 0 ; i < ( 1 << ra.size() ) ; i++ ){
        int id = 0;
        ll _i = i, val = 0;
        for( int j = 0 ; j < ra.size() ; j++ ){
            if( _i & 1LL ){
                id++;
                val += ra[j];
            }
            _i >>= 1;
        }
        rax[id].push_back( val );
    }
    for( int i = 0 ; i < ra.size() ; i++ )
        sort( rax[i].begin(), rax[i].end() );
    for( int i = 0 ; i <= la.size() ; i++ ){
        for( int j = 0 ; j < lax[i].size() ; j++ ){
            if( K - i >= 0 && K - i <= ra.size() )
                res += upper_bound( rax[K-i].begin(), rax[K-i].end(), R - lax[i][j] ) - lower_bound( rax[K-i].begin(), rax[K-i].end(), L - lax[i][j] );
        }
    }
    cout << res << endl;
    
}
accuracy: 1
time_ms: 280
memory_kb: 23428
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0;i<(int)(n);++i)
int N,K;
using ll=long long;
ll L,R,a[40];
vector<ll>sum[2][20+1];
signed main(){
  cin.tie(0)->sync_with_stdio(0);
  cin>>N>>K>>L>>R;
  rep(i,N)cin>>a[i];
  vector<vector<ll>>p(2);
  rep(i,N)p[i%2].emplace_back(a[i]);
  rep(i,2){
    rep(bit,1<<p[i].size()){
      int pc=0;
      ll s=0;
      rep(j,p[i].size()){
        if(bit&(1<<j)){
          ++pc;
          s+=p[i][j];
        }
      }
      sum[i][pc].emplace_back(s);
    }
  }
  rep(i,20+1)sort(sum[1][i].begin(),sum[1][i].end());
  ll ans=0;
  rep(c,20+1){
    int d=K-c;
    if(d<0||20<d)continue;
    for(const auto&s:sum[0][c]){
      ans+=distance(lower_bound(sum[1][d].begin(),sum[1][d].end(),L-s),upper_bound(sum[1][d].begin(),sum[1][d].end(),R-s));
    }
  }
  cout<<ans<<endl;
}
accuracy: 1
time_ms: 270
memory_kb: 25708
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0;i<(int)(n);++i)
int N,K;
using ll=long long;
ll L,R,a[40];
vector<ll>sum[2][20+1];
signed main(){
  cin.tie(0)->sync_with_stdio(0);
  cin>>N>>K>>L>>R;
  rep(i,N)cin>>a[i];
  vector<vector<ll>>p(2);
  rep(i,N)p[i%2].emplace_back(a[i]);
  rep(i,2){
    rep(bit,1<<p[i].size()){
      int pc=0;
      ll s=0;
      rep(j,p[i].size()){
        if(bit&(1<<j)){
          ++pc;
          s+=p[i][j];
        }
      }
      sum[i][pc].emplace_back(s);
    }
  }
  rep(i,20+1)sort(sum[1][i].begin(),sum[1][i].end());
  ll ans=0;
  rep(c,20+1){
    int d=K-c;
    if(d<0||20<d)break;
    for(const auto&s:sum[0][c]){
      ans+=distance(lower_bound(sum[1][d].begin(),sum[1][d].end(),L-s),upper_bound(sum[1][d].begin(),sum[1][d].end(),R-s));
    }
  }
  cout<<ans<<endl;
}
accuracy: 0.5625
time_ms: 30
memory_kb: 7108
final_rank: 19

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0;i<(int)(n);++i)
int N,K;
using ll=long long;
ll L,R,a[40];
vector<ll>sum[2][20+1];
signed main(){
  cin.tie(0)->sync_with_stdio(0);
  cin>>N>>K>>L>>R;
  rep(i,N)cin>>a[i];
  vector<vector<ll>>p(2);
  rep(i,N)p[i%2].emplace_back(a[i]);
  rep(i,2){
    rep(bit,1<<p[i].size()){
      int pc=0;
      ll s=0;
      rep(j,p[i].size()){
        if(bit&(1<<j)){
          ++pc;
          s+=p[i][j];
        }
      }
      sum[i][pc].emplace_back(s);
    }
  }
  rep(i,20+1)sort(sum[1][i].begin(),sum[1][i].end());
  ll ans=0;
  rep(c,20+1){
    int d=K-c;
    if(d<0)break;
    for(const auto&s:sum[0][c]){
      ans+=distance(lower_bound(sum[1][d].begin(),sum[1][d].end(),L-s),upper_bound(sum[1][d].begin(),sum[1][d].end(),R-s));
    }
  }
  cout<<ans<<endl;
}
accuracy: 0.59375
time_ms: 30
memory_kb: 7108
final_rank: 17

code_snippet: #include <bits/stdc++.h>


using namespace std;


using ll = long long;
using v_int = vector<int>;
using v_ll = vector<long long>;
using vv_int = vector<vector<int>>;
using vv_ll = vector<vector<long long>>;
using vvv_ll =vector<vv_ll>;
using p_ii = pair<int,int>;
using p_ll = pair<long long,long long>;
using v_string = vector<string>;

#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define sorted(X) sort(X.begin(),X.end())
#define ALL(a) (a).begin(), (a).end()

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }
long long INF = 1LL<<60;



int main(){
    ll t;
    cin >> t;

    ll N = t/2;
    ll M = t-N;

    ll K,L,R;
    cin >> K >> L>>R;

    v_ll A(N);
    v_ll B(M);
    rep(i,N){
        cin >> A[i];
    }
    rep(i,M){
        cin >> B[i];
    }

    vv_ll A_com(max(N+1,K+1));
    vv_ll B_com(max(M+1,K+1));

    for(ll bit=0;bit<(1LL<<N);bit++){
        ll pop_cnt=0;
        ll sum=0;
        for(ll i=0;i<N;i++){
            if(bit&(1LL<<i)){
                sum += A[i];
                pop_cnt++;
            }
        }

        A_com[pop_cnt].push_back(sum);
    }
    for(ll bit=0;bit<(1LL<<M);bit++){
        ll pop_cnt=0;
        ll sum=0;
        for(ll i=0;i<M;i++){
            if(bit&(1LL<<i)){
                sum += B[i];
                pop_cnt++;
            }
        }

        B_com[pop_cnt].push_back(sum);
    }

    ll ans = 0;
    for(ll i=0;i<=K;i++){
        sort(ALL(B_com[i]));
    }

    for(ll i=0;i<=K;i++){
        for(ll j=0;j<A_com[i].size();j++){
            if(R-A_com[i][j] < 0) continue;
            ll Lp = max(L- A_com[i][j],0LL);
            ll Rp = R-A_com[i][j];

            auto L_it = lower_bound(ALL(B_com[K-i]),Lp);
            auto R_it= upper_bound(ALL(B_com[K-i]),Rp);

            ans += R_it-L_it;
        }
    }

    cout << ans << endl;




}
accuracy: 1
time_ms: 280
memory_kb: 23420
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define all(a) a.begin(),a.end()
using ll = long long;

int main() {
    int N, K; ll L, R;
    cin >> N >> K >> L >> R;
    vector<ll> V(N);
    rep(i,N) cin >> V[i];

    int a = N/2, b = N-a;
    vector<pair<int,ll>> A;
    vector<vector<ll>> B(b+1);

    for (int bit=0; bit<(1<<a); bit++) {
        int cnt = 0;
        ll price = 0;
        rep(i,a) {
            if ((bit>>i) & 1) {
                cnt++;
                price += V[i];
            }
        }
        A.emplace_back(make_pair(cnt, price));
    }
    for (int bit=0; bit<(1<<b); bit++) {
        int cnt = 0;
        ll price = 0;
        rep(i,b) {
            if ((bit>>i) & 1) {
                cnt++;
                price += V[a+i];
            }
        }
        B[cnt].emplace_back(price);
    }

    rep(i,b+1) {
        sort(all(B[i]));
    }

    ll ans = 0;
    rep(i, A.size()) {
        int cnt = K - A[i].first;
        ll l = L - A[i].second, r = R - A[i].second;
        if (0 <= cnt && cnt <= b) {
            ans += upper_bound(all(B[cnt]), r) - lower_bound(all(B[cnt]), l);
        }
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 320
memory_kb: 33020
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using pll = pair<ll, ll>;
const ll INF = LLONG_MAX / 4;
const ll mod1 = 1000000007;
const ll mod9 = 998244353;
const ll Hash = 10000000000000061;
#define all(a) (a).begin(),(a).end()
#define rep(i, n) for (ll i = 0; (i) < (n); ++(i))
#define reps(i, l, r) for(ll i = (l); (i) < (r); ++(i))
ll dx[8] = {1, 1, 0, -1, -1, -1, 0, 1};
ll dy[8] = {0, -1, -1, -1, 0, 1, 1, 1};
template <typename T>
bool chmax(T &a, const T& b) {
    if (a < b) { a = b; return true; }
    return false;
}
template <typename T>
bool chmin(T &a, const T& b) {
    if (a > b) { a = b; return true; }
    return false;
}

#define EPS (1e-10)
#define equals(a, b) (fabs((a) - (b)) < EPS)
class Point {
public:
    ld x;
    ld y;
    Point(ld _x = 0, ld _y = 0) : x(_x), y(_y) {}
    Point operator+(Point p) { return Point(x + p.x, y + p.y); }
    Point operator-(Point p) { return Point(x - p.x, y - p.y); }
    Point operator*(ld a) { return Point(a * x, a * y); }
    Point operator/(ld a) { return Point(x / a, y / a); }

    ld abs() { return sqrt(norm()); }
ld norm() { return x * x + y * y; }

    bool operator<(const Point& p) const {
        return !equals(x, p.x) ? x < p.x : y < p.y;
    }
    bool operator==(const Point& p) const {
        return fabs(x - p.x) < (1e-10) && fabs(y - p.y) < (1e-10);
    }
};
typedef Point Vector;
struct Segment {
    Point A;
    Point B;
};
typedef Segment Line;
class Circle {
public:
    Point C;
    ld r;
    Circle(Point C = Point(), ld r = 0.0) : C(C), r(r) {}
};
typedef vector<Point> Polygon;

void solve(){
    ll N, K, L, R; cin >> N >> K >> L >> R; R++;
    vector<ll> a(N); rep(i, N) cin >> a[i];
    vector<ll> b;
    rep(i, N/2){
        b.push_back(a.back());
        a.pop_back();
    }
    sort(all(a)); sort(all(b));
    ll A = a.size(), B = b.size();
    vector<vector<ll>> c(A+1), d(B+1);
    rep(bit, (1<<A)){
        ll pp = __builtin_popcount(bit);
        ll x = 0;
        rep(i, A){
            if((bit>>i) & 1){
                x += a[i];
            }
        }
        c[pp].push_back(x);
    }
    rep(i, A+1) sort(all(c[i]));
    rep(bit, (1<<B)){
        ll pp = __builtin_popcount(bit);
        ll x = 0;
        rep(i, B){
            if((bit>>i) & 1){
                x += b[i];
            }
        }
        d[pp].push_back(x);
    }
    rep(i, B+1) sort(all(d[i]));
    ll ans = 0;
    rep(i, A+1){
        rep(k, B+1){
            if(i+k != K) continue;
            for(ll x : c[i]){
                ans += (lower_bound(all(d[k]), R - x) - lower_bound(all(d[k]), L-x));
            }
        }
    }
    cout << ans << endl;
}

int main(){
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);
    
    solve();
}
accuracy: 1
time_ms: 210
memory_kb: 23084
final_rank: 5

code_snippet: // #ifndef ONLINE_JUDGE
// #define _GLIBCXX_DEBUG//[]で配列外参照をするとエラーにしてくれる。上下のやつがないとTLEになるので注意 ABC311Eのサンプル4みたいなデバック中のTLEは防げないので注意
// #endif

#include <bits/stdc++.h>
using namespace std;
// #include <atcoder/all>
// using namespace atcoder;


template<typename T> using vc = vector<T>;//prioriy_queueに必要なのでここにこれ書いてます
template<typename T> using vv = vc<vc<T>>;

//-------------1.型系---------------
using ll = long long;
ll INF = 2e18;

// #include <boost/multiprecision/cpp_int.hpp>//インストール的なのをしてないとできないので注意
// namespace multip = boost::multiprecision;
// //using lll = multip::cpp_int;//無制限を使いたいときはこっちを使う
// using lll = multip::int128_t;

using ld = long double;
using bl = bool;
// using mint = modint998244353;
//using mint = modint1000000007;
//using mint = modint;//使うときはコメントアウトを外す
//mint::set_mod(m);//使うときはコメントアウトを外す

template<class T> using pq = priority_queue<T, vc<T>>;//大きい順
template<class T> using pq_g = priority_queue<T, vc<T>, greater<T>>;//小さい順
//-----------------------------------



//-------------2.配列系--------------
using vl = vc<ll>; using vvl = vv<ll>; using vvvl = vv<vl>; using vvvvl = vv<vvl>;
using vs = vc<string>; using vvs = vv<string>;
using vb = vc<bl>; using vvb = vv<bl>; using vvvb = vv<vb>;
using vld = vc<ld>; using vvld = vv<ld>; using vvvld = vv<vld>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
// using vmint = vc<mint>; using vvmint = vv<mint>; using vvvmint = vv<vmint>;

//配列外参照対策のやつは一番上の行にあります

#define rep(i,n) for(ll i = 0; i < (n); ++i)//↓でrepを使うので書いてます
template<class T>istream& operator>>(istream& i, vc<T>& v) { rep(j, size(v))i >> v[j]; return i; }

using ar2 = array<ll, 2>;

//----------------------------------



//--------3.コード短縮化とか---------
#define rep(i,n) for(ll i = 0; i < (n); ++i)
#define rrep(i,n) for(ll i = 1; i <= (n); ++i)
#define drep(i,n) for(ll i = (n)-1; i >= 0; --i)
#define nfor(i,s,n) for(ll i=s;i<n;i++)//i=s,s+1...n-1 ノーマルfor
#define dfor(i,s,n) for(ll i = (s)-1; i>=n;i--)//s-1スタートでnまで落ちる

#define nall(a) a.begin(),a.end()
#define rall(a) a.rbegin(),a.rend()

#define chmax(x,y) x = max(x,y)
#define chmin(x,y) x = min(x,y)

#define pb push_back
#define eb emplace_back
#define em emplace
#define pob pop_back


#define YES cout<<"Yes"<<endl
#define NO cout<<"No"<<endl
#define YN {cout<<"Yes"<<endl;}else{cout<<"No"<<endl;}// if(a==b)YN;
#define dame cout<<-1<<endl


#define vc_unique(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define vc_rotate(v) rotate(v.begin(),v.begin()+1,v.end());

#define pop_cnt(s) ll(popcount(uint64_t(s)))

#define next_p(v) next_permutation(v.begin(),v.end())

//if (regex_match(s, regex("")))YN;//文字列sの判定を行う。コメントアウトを外して「""」の中に判定する内容を入れる

//-------------------------------




//---------4.グリッド系----------
vl di = { 0,1,0,-1 };//vl di={0,1,1,1,0,-1,-1,-1};
vl dj = { 1,0,-1,0 };//vl dj={1,1,0,-1,-1,-1,0,1};

bool out_grid(ll i, ll j, ll h, ll w) {//trueならcontinue
    return (!(0 <= i && i < h && 0 <= j && j < w));
}

#define vvl_kaiten_r(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[j][n-i-1]=v[i][j];swap(nx,v);}//時計回りに90°回転
#define vvl_kaiten_l(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//反時計周りに90°回転

#define vs_kaiten_r(v) {ll n = size(v);vs nx(n,string(n,'.'));rep(i,n)rep(j,n)nx[j][n-i-1]=v[i][j];swap(nx,v);}//文字列版 時計回りに90°回転
#define vs_kaiten_l(v) {ll n = size(v);vs nx(n,string(n,'.'));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//文字列版　反時計周りに90°回転


#define vvl_tenti(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[j][i]=v[i][j];swap(nx,v);}
#define vs_tenti(v) {ll n = size(v); vs nx(n, string(n,'.')); rep(i, n)rep(j, n)nx[j][i] = v[i][j]; swap(nx, v);}

//--------------------------------




//-----------5.数学系--------------
#define yu_qurid(x,y) ((x)*(x)+(y)*(y))//ユークリッド距離 sqrtはしてないなので注意
#define mannhattan(x1,x2,y1,y2) (abs(x1-x2)+abs(y1-y2)) // マンハッタン距離 = |x1-x2|+|y1-y2|

template<class T>T tousa_sum1(T l, T d, T r) {//初項,公差,末項 で総和を求める
    T wide = (r - l) / d + 1;
    return (l + r) * wide / 2;
}
template<class T>T tousa_sum2(T a, T d, T n) {//初項,交差,項数 で総和を求める
    return (a * 2 + d * (n - 1)) * n / 2;
}
ll kousa_kousuu(ll l, ll r, ll d) {//初項,末項,交差 で等差数列の項数を求める
    return (r - l) / d + 1;
}
// mint touhi_sum(mint a, mint r, ll n) {//初項,公比,項数で等比数列の総和を求める
//     if (r == 1) {
//         return a * n;
//     }
//     mint bunsi = a * (r.pow(n) - mint(1));
//     mint bunbo = r - 1;
//     return bunsi / bunbo;
// }

ll nc2(ll x) { return x * (x - 1) / 2; }
ll nc3(ll x) { return x * (x - 1) * (x - 2) / 6; }

//----------------------------------------------




//-----------6.デバックや出力系------------------
void print(ld x) { printf("%.20Lf\n", x); }

void mukou_debug(vvl to, bool yukou) {//GRAPH × GRAPH用の無向グラフを出力する
    ll n = size(to); ll cnt = 0;//辺の本数
    vc<pair<ll, ll>>v; rep(i, n)for (ll t : to[i])  if (i < t || yukou)cnt++, v.eb(i + 1, t + 1);//有向グラフなら全部OK、違うなら無向なのでf<tのみ見る、using Pのやつを別のにしたいときのためにPを使わずにpair<ll,ll>にしてる
    cout << n << ' ' << cnt << endl; for (auto [f, t] : v)cout << f << ' ' << t << endl;
}

#define vc_cout(v){ll n = size(v);rep(i,n)cout<<v[i]<<endl;}//一次元配列を出力する
#define vv_cout(v){ll n = size(v);rep(i,n){rep(j,size(v[i])){cout<<v[i][j]<<' ';}cout<<endl;}}//二次元配列を出力する

int main(){
    ll n, k, l, r;
    cin >> n >> k >> l >> r;
    vl a(n);
    rep(i, n) cin >> a[i];

    vvl list1(21, vl()), list2(21, vl());
    ll n1 = n/2, n2 = n - n/2;

    for(ll bit = 0; bit < (1 << n1); bit++){
        ll cnt = 0, sum = 0;
        rep(i, n1){
            ll mask = (1ll << i);
            if(bit & mask){
                cnt++;
                sum += a[i];
            }
        }
        list1[cnt].pb(sum);
    }

    for(ll bit = 0; bit < (1 << n2); bit++){
        ll cnt = 0, sum = 0;
        rep(i, n2){
            ll mask = (1ll << i);
            if(bit & mask){
                cnt++;
                sum += a[i + n1];
            }
        }
        list2[cnt].pb(sum);
    }

    for(ll i = 0; i <= n2; i++) sort(nall(list2[i]));

    ll ans = 0;
    rep(i, n1+1){
        if(k - i < 0 || i + n2 < k) continue;

        for(ll a : list1[i]){
            auto it1 = upper_bound(nall(list2[k-i]), r-a);
            auto it2 = lower_bound(nall(list2[k-i]), l-a);

            ans += it1 - it2;
        }
    }

    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 300
memory_kb: 23392
final_rank: 14

code_snippet: // #ifndef ONLINE_JUDGE
// #define _GLIBCXX_DEBUG//[]で配列外参照をするとエラーにしてくれる。上下のやつがないとTLEになるので注意 ABC311Eのサンプル4みたいなデバック中のTLEは防げないので注意
// #endif

#include <bits/stdc++.h>
using namespace std;
// #include <atcoder/all>
// using namespace atcoder;


template<typename T> using vc = vector<T>;//prioriy_queueに必要なのでここにこれ書いてます
template<typename T> using vv = vc<vc<T>>;

//-------------1.型系---------------
using ll = long long;
ll INF = 2e18;

// #include <boost/multiprecision/cpp_int.hpp>//インストール的なのをしてないとできないので注意
// namespace multip = boost::multiprecision;
// //using lll = multip::cpp_int;//無制限を使いたいときはこっちを使う
// using lll = multip::int128_t;

using ld = long double;
using bl = bool;
// using mint = modint998244353;
//using mint = modint1000000007;
//using mint = modint;//使うときはコメントアウトを外す
//mint::set_mod(m);//使うときはコメントアウトを外す

template<class T> using pq = priority_queue<T, vc<T>>;//大きい順
template<class T> using pq_g = priority_queue<T, vc<T>, greater<T>>;//小さい順
//-----------------------------------



//-------------2.配列系--------------
using vl = vc<ll>; using vvl = vv<ll>; using vvvl = vv<vl>; using vvvvl = vv<vvl>;
using vs = vc<string>; using vvs = vv<string>;
using vb = vc<bl>; using vvb = vv<bl>; using vvvb = vv<vb>;
using vld = vc<ld>; using vvld = vv<ld>; using vvvld = vv<vld>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
// using vmint = vc<mint>; using vvmint = vv<mint>; using vvvmint = vv<vmint>;

//配列外参照対策のやつは一番上の行にあります

#define rep(i,n) for(ll i = 0; i < (n); ++i)//↓でrepを使うので書いてます
template<class T>istream& operator>>(istream& i, vc<T>& v) { rep(j, size(v))i >> v[j]; return i; }

using ar2 = array<ll, 2>;

//----------------------------------



//--------3.コード短縮化とか---------
#define rep(i,n) for(ll i = 0; i < (n); ++i)
#define rrep(i,n) for(ll i = 1; i <= (n); ++i)
#define drep(i,n) for(ll i = (n)-1; i >= 0; --i)
#define nfor(i,s,n) for(ll i=s;i<n;i++)//i=s,s+1...n-1 ノーマルfor
#define dfor(i,s,n) for(ll i = (s)-1; i>=n;i--)//s-1スタートでnまで落ちる

#define nall(a) a.begin(),a.end()
#define rall(a) a.rbegin(),a.rend()

#define chmax(x,y) x = max(x,y)
#define chmin(x,y) x = min(x,y)

#define pb push_back
#define eb emplace_back
#define em emplace
#define pob pop_back


#define YES cout<<"Yes"<<endl
#define NO cout<<"No"<<endl
#define YN {cout<<"Yes"<<endl;}else{cout<<"No"<<endl;}// if(a==b)YN;
#define dame cout<<-1<<endl


#define vc_unique(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define vc_rotate(v) rotate(v.begin(),v.begin()+1,v.end());

#define pop_cnt(s) ll(popcount(uint64_t(s)))

#define next_p(v) next_permutation(v.begin(),v.end())

//if (regex_match(s, regex("")))YN;//文字列sの判定を行う。コメントアウトを外して「""」の中に判定する内容を入れる

//-------------------------------




//---------4.グリッド系----------
vl di = { 0,1,0,-1 };//vl di={0,1,1,1,0,-1,-1,-1};
vl dj = { 1,0,-1,0 };//vl dj={1,1,0,-1,-1,-1,0,1};

bool out_grid(ll i, ll j, ll h, ll w) {//trueならcontinue
    return (!(0 <= i && i < h && 0 <= j && j < w));
}

#define vvl_kaiten_r(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[j][n-i-1]=v[i][j];swap(nx,v);}//時計回りに90°回転
#define vvl_kaiten_l(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//反時計周りに90°回転

#define vs_kaiten_r(v) {ll n = size(v);vs nx(n,string(n,'.'));rep(i,n)rep(j,n)nx[j][n-i-1]=v[i][j];swap(nx,v);}//文字列版 時計回りに90°回転
#define vs_kaiten_l(v) {ll n = size(v);vs nx(n,string(n,'.'));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//文字列版　反時計周りに90°回転


#define vvl_tenti(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[j][i]=v[i][j];swap(nx,v);}
#define vs_tenti(v) {ll n = size(v); vs nx(n, string(n,'.')); rep(i, n)rep(j, n)nx[j][i] = v[i][j]; swap(nx, v);}

//--------------------------------




//-----------5.数学系--------------
#define yu_qurid(x,y) ((x)*(x)+(y)*(y))//ユークリッド距離 sqrtはしてないなので注意
#define mannhattan(x1,x2,y1,y2) (abs(x1-x2)+abs(y1-y2)) // マンハッタン距離 = |x1-x2|+|y1-y2|

template<class T>T tousa_sum1(T l, T d, T r) {//初項,公差,末項 で総和を求める
    T wide = (r - l) / d + 1;
    return (l + r) * wide / 2;
}
template<class T>T tousa_sum2(T a, T d, T n) {//初項,交差,項数 で総和を求める
    return (a * 2 + d * (n - 1)) * n / 2;
}
ll kousa_kousuu(ll l, ll r, ll d) {//初項,末項,交差 で等差数列の項数を求める
    return (r - l) / d + 1;
}
// mint touhi_sum(mint a, mint r, ll n) {//初項,公比,項数で等比数列の総和を求める
//     if (r == 1) {
//         return a * n;
//     }
//     mint bunsi = a * (r.pow(n) - mint(1));
//     mint bunbo = r - 1;
//     return bunsi / bunbo;
// }

ll nc2(ll x) { return x * (x - 1) / 2; }
ll nc3(ll x) { return x * (x - 1) * (x - 2) / 6; }

//----------------------------------------------




//-----------6.デバックや出力系------------------
void print(ld x) { printf("%.20Lf\n", x); }

void mukou_debug(vvl to, bool yukou) {//GRAPH × GRAPH用の無向グラフを出力する
    ll n = size(to); ll cnt = 0;//辺の本数
    vc<pair<ll, ll>>v; rep(i, n)for (ll t : to[i])  if (i < t || yukou)cnt++, v.eb(i + 1, t + 1);//有向グラフなら全部OK、違うなら無向なのでf<tのみ見る、using Pのやつを別のにしたいときのためにPを使わずにpair<ll,ll>にしてる
    cout << n << ' ' << cnt << endl; for (auto [f, t] : v)cout << f << ' ' << t << endl;
}

#define vc_cout(v){ll n = size(v);rep(i,n)cout<<v[i]<<endl;}//一次元配列を出力する
#define vv_cout(v){ll n = size(v);rep(i,n){rep(j,size(v[i])){cout<<v[i][j]<<' ';}cout<<endl;}}//二次元配列を出力する

int main(){
    ll n, k, l, r;
    cin >> n >> k >> l >> r;
    vl a(n);
    rep(i, n) cin >> a[i];

    vvl list1(21, vl()), list2(21, vl());
    ll n1 = n/2, n2 = n - n/2;

    for(ll bit = 0; bit < (1 << n1); bit++){
        ll cnt = 0, sum = 0;
        rep(i, n1){
            ll mask = (1ll << i);
            if(bit & mask){
                cnt++;
                sum += a[i];
            }
        }
        list1[cnt].pb(sum);
    }
    for(ll bit = 0; bit < (1 << n2); bit++){
        ll cnt = 0, sum = 0;
        rep(i, n2){
            ll mask = (1ll << i);
            if(bit & mask){
                cnt++;
                sum += a[i + n1];
            }
        }
        list2[cnt].pb(sum);
    }

    for(ll i = 0; i <= n2; i++) sort(nall(list2[i]));

    ll ans = 0;
    rep(i, n1+1){
        for(ll a : list1[i]){
            auto it1 = upper_bound(nall(list2[k-i]), r-a);
            auto it2 = lower_bound(nall(list2[k-i]), l-a);

            ans += it1 - it2;
        }
    }

    cout << ans << endl;

    return 0;
}
accuracy: 0.5625
time_ms: 30
memory_kb: 6720
final_rank: 18

code_snippet: // #ifndef ONLINE_JUDGE
// #define _GLIBCXX_DEBUG//[]で配列外参照をするとエラーにしてくれる。上下のやつがないとTLEになるので注意 ABC311Eのサンプル4みたいなデバック中のTLEは防げないので注意
// #endif

#include <bits/stdc++.h>
using namespace std;
// #include <atcoder/all>
// using namespace atcoder;


template<typename T> using vc = vector<T>;//prioriy_queueに必要なのでここにこれ書いてます
template<typename T> using vv = vc<vc<T>>;

//-------------1.型系---------------
using ll = long long;
ll INF = 2e18;

// #include <boost/multiprecision/cpp_int.hpp>//インストール的なのをしてないとできないので注意
// namespace multip = boost::multiprecision;
// //using lll = multip::cpp_int;//無制限を使いたいときはこっちを使う
// using lll = multip::int128_t;

using ld = long double;
using bl = bool;
// using mint = modint998244353;
//using mint = modint1000000007;
//using mint = modint;//使うときはコメントアウトを外す
//mint::set_mod(m);//使うときはコメントアウトを外す

template<class T> using pq = priority_queue<T, vc<T>>;//大きい順
template<class T> using pq_g = priority_queue<T, vc<T>, greater<T>>;//小さい順
//-----------------------------------



//-------------2.配列系--------------
using vl = vc<ll>; using vvl = vv<ll>; using vvvl = vv<vl>; using vvvvl = vv<vvl>;
using vs = vc<string>; using vvs = vv<string>;
using vb = vc<bl>; using vvb = vv<bl>; using vvvb = vv<vb>;
using vld = vc<ld>; using vvld = vv<ld>; using vvvld = vv<vld>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
// using vmint = vc<mint>; using vvmint = vv<mint>; using vvvmint = vv<vmint>;

//配列外参照対策のやつは一番上の行にあります

#define rep(i,n) for(ll i = 0; i < (n); ++i)//↓でrepを使うので書いてます
template<class T>istream& operator>>(istream& i, vc<T>& v) { rep(j, size(v))i >> v[j]; return i; }

using ar2 = array<ll, 2>;

//----------------------------------



//--------3.コード短縮化とか---------
#define rep(i,n) for(ll i = 0; i < (n); ++i)
#define rrep(i,n) for(ll i = 1; i <= (n); ++i)
#define drep(i,n) for(ll i = (n)-1; i >= 0; --i)
#define nfor(i,s,n) for(ll i=s;i<n;i++)//i=s,s+1...n-1 ノーマルfor
#define dfor(i,s,n) for(ll i = (s)-1; i>=n;i--)//s-1スタートでnまで落ちる

#define nall(a) a.begin(),a.end()
#define rall(a) a.rbegin(),a.rend()

#define chmax(x,y) x = max(x,y)
#define chmin(x,y) x = min(x,y)

#define pb push_back
#define eb emplace_back
#define em emplace
#define pob pop_back


#define YES cout<<"Yes"<<endl
#define NO cout<<"No"<<endl
#define YN {cout<<"Yes"<<endl;}else{cout<<"No"<<endl;}// if(a==b)YN;
#define dame cout<<-1<<endl


#define vc_unique(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define vc_rotate(v) rotate(v.begin(),v.begin()+1,v.end());

#define pop_cnt(s) ll(popcount(uint64_t(s)))

#define next_p(v) next_permutation(v.begin(),v.end())

//if (regex_match(s, regex("")))YN;//文字列sの判定を行う。コメントアウトを外して「""」の中に判定する内容を入れる

//-------------------------------




//---------4.グリッド系----------
vl di = { 0,1,0,-1 };//vl di={0,1,1,1,0,-1,-1,-1};
vl dj = { 1,0,-1,0 };//vl dj={1,1,0,-1,-1,-1,0,1};

bool out_grid(ll i, ll j, ll h, ll w) {//trueならcontinue
    return (!(0 <= i && i < h && 0 <= j && j < w));
}

#define vvl_kaiten_r(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[j][n-i-1]=v[i][j];swap(nx,v);}//時計回りに90°回転
#define vvl_kaiten_l(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//反時計周りに90°回転

#define vs_kaiten_r(v) {ll n = size(v);vs nx(n,string(n,'.'));rep(i,n)rep(j,n)nx[j][n-i-1]=v[i][j];swap(nx,v);}//文字列版 時計回りに90°回転
#define vs_kaiten_l(v) {ll n = size(v);vs nx(n,string(n,'.'));rep(i,n)rep(j,n)nx[n-j-1][i]=v[i][j];swap(nx,v);}//文字列版　反時計周りに90°回転


#define vvl_tenti(v) {ll n = size(v);vvl nx(n,vl(n));rep(i,n)rep(j,n)nx[j][i]=v[i][j];swap(nx,v);}
#define vs_tenti(v) {ll n = size(v); vs nx(n, string(n,'.')); rep(i, n)rep(j, n)nx[j][i] = v[i][j]; swap(nx, v);}

//--------------------------------




//-----------5.数学系--------------
#define yu_qurid(x,y) ((x)*(x)+(y)*(y))//ユークリッド距離 sqrtはしてないなので注意
#define mannhattan(x1,x2,y1,y2) (abs(x1-x2)+abs(y1-y2)) // マンハッタン距離 = |x1-x2|+|y1-y2|

template<class T>T tousa_sum1(T l, T d, T r) {//初項,公差,末項 で総和を求める
    T wide = (r - l) / d + 1;
    return (l + r) * wide / 2;
}
template<class T>T tousa_sum2(T a, T d, T n) {//初項,交差,項数 で総和を求める
    return (a * 2 + d * (n - 1)) * n / 2;
}
ll kousa_kousuu(ll l, ll r, ll d) {//初項,末項,交差 で等差数列の項数を求める
    return (r - l) / d + 1;
}
// mint touhi_sum(mint a, mint r, ll n) {//初項,公比,項数で等比数列の総和を求める
//     if (r == 1) {
//         return a * n;
//     }
//     mint bunsi = a * (r.pow(n) - mint(1));
//     mint bunbo = r - 1;
//     return bunsi / bunbo;
// }

ll nc2(ll x) { return x * (x - 1) / 2; }
ll nc3(ll x) { return x * (x - 1) * (x - 2) / 6; }

//----------------------------------------------




//-----------6.デバックや出力系------------------
void print(ld x) { printf("%.20Lf\n", x); }

void mukou_debug(vvl to, bool yukou) {//GRAPH × GRAPH用の無向グラフを出力する
    ll n = size(to); ll cnt = 0;//辺の本数
    vc<pair<ll, ll>>v; rep(i, n)for (ll t : to[i])  if (i < t || yukou)cnt++, v.eb(i + 1, t + 1);//有向グラフなら全部OK、違うなら無向なのでf<tのみ見る、using Pのやつを別のにしたいときのためにPを使わずにpair<ll,ll>にしてる
    cout << n << ' ' << cnt << endl; for (auto [f, t] : v)cout << f << ' ' << t << endl;
}

#define vc_cout(v){ll n = size(v);rep(i,n)cout<<v[i]<<endl;}//一次元配列を出力する
#define vv_cout(v){ll n = size(v);rep(i,n){rep(j,size(v[i])){cout<<v[i][j]<<' ';}cout<<endl;}}//二次元配列を出力する

void rec(vl &a, ll i, ll cnt, ll n, ll val, vl &res){
    if(cnt == n){
        res.pb(val);
        return;
    }

    for(ll j = i; j < a.size(); j++){
        if (a.size() - i < n - cnt) break;
        rec(a, j+1, cnt+1, n, val+a[j], res);
    }

    return;
}

int main(){
    ll n, k, l, r;
    cin >> n >> k >> l >> r;
    vl a(n);
    rep(i, n) cin >> a[i];

    vl b, c;
    rep(i, n/2){
        b.pb(a[i]);
    }
    nfor(i, n/2, n){
        c.pb(a[i]);
    }

    ll ans = 0;
    for(ll kk = 0; kk <= k; kk++){
        if(b.size() < kk || c.size() < k-kk) continue;

        vl bb, cc;

        if (kk == 0) bb.pb(0); else rec(b, 0, 0, kk, 0, bb);
        if (k - kk == 0) cc.pb(0); else rec(c, 0, 0, k - kk, 0, cc);

        sort(nall(cc));

        for(ll x : bb){
            ll i = lower_bound(nall(cc), l-x) - cc.begin();
            ll j = upper_bound(nall(cc), r-x) - cc.begin();

            ans += j - i;
        }
    }

    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 8096
final_rank: 1

code_snippet: // #include <atcoder/all>
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr ll inf = (1LL << 61);
ll dx[4] = {0, 1, 0, -1};
ll dy[4] = {-1, 0, 1, 0};
#define rep(i, n) for (ll i = 0; i < (ll)(n); ++i)
#define REP(i, init, n) for (ll i = (ll)init; i < (ll)(n); ++i)
// ll op(ll a, ll b) { return min(a, b); }
// ll e() { return inf; }

ll a[200005];
int main() {
  ll n, k, l, r;
  cin >> n >> k >> l >> r;
  rep(i, n) cin >> a[i];
  ll L = n / 2, R = n - L;
  vector<vector<ll>> left(L + 1);
  rep(i, 1 << L) {
    ll cnt = 0, sum = 0;
    rep(j, L) {
      if (i & (1 << j)) {
        sum += a[j];
        cnt++;
      }
    }
    left[cnt].push_back(sum);
  }
  for (auto& v : left) sort(v.begin(), v.end());
  ll ans = 0;
  rep(i, 1 << R) {
    ll cnt = 0, sum = 0;
    rep(j, R) {
      if (i & (1 << j)) {
        sum += a[L + j];
        cnt++;
      }
    }
    ll need = k - cnt;
    if (need < 0 || need > L) continue;
    auto it = lower_bound(left[need].begin(), left[need].end(), l - sum);
    auto it2 = upper_bound(left[need].begin(), left[need].end(), r - sum);
    ans += it2 - it;
  }
  cout << ans << endl;
}
accuracy: 1
time_ms: 330
memory_kb: 12612
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
using lli=long long int;
using ld=long double;
using vi=vector<int>;
using vvi=vector<vi>;
using vvvi=vector<vvi>;
using vvvvi=vector<vvvi>;
using vl=vector<lli>;
using vvl=vector<vl>;
using vb=vector<bool>;
using vvb=vector<vb>;
#define rep(i,s,e) for(int i=s;i<e;i++)
#define repl(i,s,e) for(lli i=s;i<e;i++)
#define rrep(i,s,e) for(int i=s-1;i>=e;i--)
#define in(v,seq) for(auto v:seq)
#define veci(v,s) vi v(s); rep(i,0,s) cin >> v.at(i);
#define vecl(v,s) vl v(s); rep(i,0,s) cin >> v.at(i);
#define all(s) s.begin(),s.end()
#define rall(s) s.rbegin(),s.rend()
using pii=pair<int,int>;
using pll=pair<lli,lli>;
#define mp(f,s) make_pair(f,s)
#define fi first
#define se second
using vpii=vector<pii>;
using vpll=vector<pll>;
#define vecpii(v,s) vpii v(s); rep(i,0,s) cin >> v.at(i).fi >> v.at(i).se;
#define vecpll(v,s) vpll v(s); rep(i,0,s) cin >> v.at(i).fi >> v.at(i).se;
#define pub(x) push_back(x)
#define puf(x) push_front(x)
#define pob(x) pop_back(x)
#define pof(x) pop_front(x)
#define emb(x) emplace_back(x)
#define print(s) cout << s << endl;
const int I_INF=1<<30;
const lli LL_INF=1ll<<60;
const string alp="abcdefghijklmnopqrstuvwxyz";
const int let=alp.size(); // 26

int main(){
  int n,k; lli l,r; //[l,r]
  cin >> n >> k >> l >> r;
  int x=n/2,y=n-x;
  vecl(a,x); vecl(b,y);
  vvl mitm(x+1);

  rep(i,0,(1<<x)){
    lli res=0; int pc=0;
    rep(j,0,x){
      if(i&(1<<j)){
        res+=a.at(j);
        pc++;
      }
    }
    mitm.at(pc).pub(res);
  }

  in(&v,mitm){
    sort(all(v));
  }

  lli ans=0;
  repl(i,0,(1<<y)){
    lli res=0; int pc=k;
    rep(j,0,y){
      if(i&(1<<j)){
        res+=b.at(j);
        pc--;
      }
    }
    if(pc<0 || x<pc) continue;
    int L=lower_bound(all(mitm.at(pc)),l-res)-mitm.at(pc).begin();
    int R=upper_bound(all(mitm.at(pc)),r-res)-mitm.at(pc).begin();
    ans+=(lli)(R-L);
  }

  print(ans);
}
accuracy: 1
time_ms: 320
memory_kb: 12588
final_rank: 3