Submission #1125853

#TimeUsernameProblemLanguageResultExecution timeMemory
1125853_callmelucianNoM (RMI21_nom)C++17
100 / 100
105 ms15220 KiB
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<ll,ll> pl;
typedef pair<int,int> pii;
typedef tuple<int,int,int> tpl;

#define all(a) a.begin(), a.end()
#define filter(a) a.erase(unique(all(a)), a.end())

const int MOD = 1e9 + 7;
int fact[4040], ifac[4040], grCount[4040], getGr[4040];
int dp[2020][2020];

int add (int a, int b) { return a + b - (a + b < MOD ? 0 : MOD); }
int sub (int a, int b) { return a - b + (a - b >= 0 ? 0 : MOD); }
int mul (int a, int b) { return 1LL * a * b % MOD; }

int binpow (int a, int b = MOD - 2) {
    int ans = 1;
    for (; b; b >>= 1) {
        if (b & 1) ans = mul(ans, a);
        a = mul(a, a);
    }
    return ans;
}

int C (int n, int k) {
    int ans = mul(fact[n], ifac[k]);
    return mul(ans, ifac[n - k]);
}

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

    /// pre-calculate combinatorics
    fact[0] = 1;
    for (int i = 1; i <= 2000; i++) fact[i] = mul(fact[i - 1], i);
    ifac[2000] = binpow(fact[2000]);
    for (int i = 2000; i >= 1; i--) ifac[i - 1] = mul(ifac[i], i);

    /// read input & pre-calculations
    int n, m, pre = 0; cin >> n >> m;
    for (int i = 0; i <= 2 * n; i++) getGr[i] = -1;
    for (int i = 0; i < m; i++) {
        grCount[i] = (2 * n) / m + (i < (2 * n) % m);
        pre += grCount[i], getGr[pre] = i;
    }

    /// run DP
    dp[0][0] = 1;
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= n && 2 * i + j <= 2 * n; j++) {
            int cur = 2 * i + j;
            if (getGr[cur] == -1) continue;
            int need = grCount[getGr[cur]];
//            cout << "state " << i << " " << j << " group " << getGr[cur] << "\n";
            for (int x = 0; x <= min(i, need); x++) {
                int y = need - x;
                if (y <= j) {
                    int contrib = mul(fact[need], mul(mul(C(i, x), binpow(2, x)), C(j, y)));
                    dp[i][j] = add(dp[i][j], mul(dp[i - x][j + x - y], contrib));
                }
            }
        }
    }
    cout << dp[n][0];

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...