/ SeriousOJ /

Record Detail

Accepted


  
# Status Time Cost Memory Cost
#1 Accepted 2ms 484.0 KiB
#2 Accepted 2ms 588.0 KiB
#3 Accepted 3ms 584.0 KiB
#4 Accepted 3ms 736.0 KiB
#5 Accepted 3ms 592.0 KiB
#6 Accepted 3ms 368.0 KiB
#7 Accepted 2ms 540.0 KiB
#8 Accepted 3ms 544.0 KiB
#9 Accepted 3ms 540.0 KiB
#10 Accepted 3ms 540.0 KiB
#11 Accepted 3ms 588.0 KiB
#12 Accepted 3ms 452.0 KiB
#13 Accepted 3ms 584.0 KiB
#14 Accepted 3ms 816.0 KiB
#15 Accepted 3ms 480.0 KiB
#16 Accepted 32ms 692.0 KiB
#17 Accepted 34ms 1.719 MiB
#18 Accepted 36ms 2.887 MiB
#19 Accepted 23ms 1.32 MiB
#20 Accepted 27ms 1.297 MiB
#21 Accepted 34ms 1.719 MiB

Code

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

typedef long long ll;

// Constants
const int MOD = 1'000'000'007;

// Function to compute x^y under modulo MOD
ll powerMod(ll x, ll y, ll mod) {
    ll res = 1;
    x %= mod;
    while(y > 0){
        if(y & 1LL){
            res = (res * x) % mod;
        }
        x = (x * x) % mod;
        y >>=1LL;
    }
    return res;
}

// Function to compute factorial and inverse factorial
struct Combinatorics {
    int max_n;
    vector<ll> factorial;
    vector<ll> inv_factorial;

    Combinatorics(int n){
        max_n = n;
        factorial.assign(max_n +1, 1LL);
        for(int i=1;i<=max_n;i++) factorial[i] = (factorial[i-1]*i)%MOD;
        
        // Compute inverse factorial using Fermat's Little Theorem
        inv_factorial.assign(max_n +1, 1LL);
        inv_factorial[max_n] = powerMod(factorial[max_n], MOD-2, MOD);
        for(int i=max_n-1;i>=0;i--) {
            inv_factorial[i] = (inv_factorial[i+1]*(i+1))%MOD;
        }
    }

    // Function to compute nCr modulo MOD
    ll nCr(int n, int r){
        if(r <0 || r >n) return 0;
        return (factorial[n]*inv_factorial[r]%MOD)*inv_factorial[n -r]%MOD;
    }
};

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

    int T;
    cin >> T;

    // Precompute powers of 2 up to 5000
    // Since N <=5e3
    vector<ll> pow2(5001, 1LL);
    for(int i=1;i<=5000;i++) pow2[i] = (pow2[i-1]*2)%MOD;

    while(T--){
        int N;
        ll K;
        cin >> N >> K;
        vector<int> A(N);
        int m=0; // number of 1's
        for(int &x:A){
            cin >> x;
            if(x ==1) m++;
        }
        int t = N -m; // number of 0's

        // Handle edge cases
        if(K ==0){
            // Any subset except removing nothing (since you must remove at least one element)
            // Total subsets: 2^N -1
            ll total = powerMod(2, N, MOD) -1;
            if(total <0) total += MOD;
            cout << total << "\n";
            continue;
        }

        if(m < K){
            // Impossible to have sum >=K
            cout << "0\n";
            continue;
        }

        // Initialize combinatorics up to m
        Combinatorics comb(m);

        // Compute sum_{i=K}^{m} C(m,i) * 2^t
        // Since t can be up to 5e3, and m up to5e3, precomputed pow2 can handle it
        // 2^t modulo MOD is pow2[t]
        ll total =0;
        for(int i=K;i<=m;i++){
            ll term = comb.nCr(m, i);
            term = (term * powerMod(2, t, MOD))%MOD;
            total = (total + term)%MOD;
        }

        // Subtract 1 if keeping all elements is valid (sum >=K)
        // Since m >=K, and keeping all elements corresponds to i=m
        // So always subtract 1
        total = (total -1 + MOD)%MOD;

        cout << total << "\n";
    }

    return 0;
}

Information

Submit By
Type
Submission
Problem
P1094 Number of ways (Hard version)
Language
C++17 (G++ 13.2.0)
Submit At
2024-10-04 03:09:49
Judged At
2024-11-11 02:43:31
Judged By
Score
100
Total Time
36ms
Peak Memory
2.887 MiB