Cod sursa(job #2839285)

Utilizator ptudortudor P ptudor Data 25 ianuarie 2022 18:30:38
Problema Padure2 Scor 100
Compilator cpp-64 Status done
Runda Arhiva ICPC Marime 2.01 kb
#include <bits/stdc++.h>
using namespace std;

ifstream in("padure2.in");
ofstream out("padure2.out");

const int mmax = 3000005, mod = 2000003;
int n, m, c;

vector<int> fact, dp;
vector<pair<int, int>> v;
bool inside(pair<int, int> small, pair<int, int> big) {
    return (small.first <= big.first && small.second <= big.second);
}
int put(int x, int y) {
    int sol = 1;
    while (y) {
        if (y % 2) {
            sol = 1LL * sol * x % mod;
        }
        x = 1LL * x * x % mod;
        y /= 2;
    }
    return sol;
}
int inv(int x) {
    return put(x, mod - 2);
}
int comb(int n, int k) {
    if (n < k) return 0;
    if (n < 0 || k < 0) return 0;

    return 1LL * fact[n] * inv(fact[n - k]) % mod * inv(fact[k]) % mod;
}

int rect(int a, int b) {
    return comb(a + b, a);
}

void selfneg(int &a, int b) {
    a = ((1LL * a - b) % mod + mod) % mod;
}
vector<int> viz;
void calc(int i) {
    dp[i] = comb(v[i].first + v[i].second - 2, v[i].first - 1);
    viz[i] = 1;
    for (int j = 1; j <= c; j++) {
        if (i == j) continue;

        if (inside(v[j], v[i])) {
            if (viz[j] == 0) {
                calc(j);
            }
            selfneg(dp[i], 1LL * dp[j] * rect(v[i].first - v[j].first, v[i].second - v[j].second) % mod);
        }
    }
}
int32_t main() {
    in >> n >> m;
    fact.resize(max(n, m) * 3 + 1);
    in >> c;
    viz.resize(c + 1);
    dp.resize(c + 1);
    fact[0] = 1;
    for (int i = 1; i <= 3 * max(n, m); i++) {
        fact[i] = 1LL * fact[i - 1] * i % mod;
    }
    v.resize(c + 1);
    for (int i = 1; i <= c; i++) {
        int y, x;
        in >> y >> x;
        v[i] = {y, x};
    }

    for (int i = 0; i <= c; i++) dp[i] = 0;
    for (int i = 1; i <= c; i++) {
        calc(i);
    }

    int sol = comb(n + m - 2, n - 1);
    for (int i = 1; i <= c; i++) {
        selfneg(sol, 1LL * dp[i] * comb(n - v[i].first + (m - v[i].second), m - v[i].second) % mod);
    }

    out << (sol + mod) % mod << "\n";
}