Cod sursa(job #2783591)

Utilizator RaresFelixTudose Rares Felix RaresFelix Data 14 octombrie 2021 19:17:08
Problema Padure2 Scor 0
Compilator cpp-64 Status done
Runda Arhiva ICPC Marime 1.57 kb
#include <bits/stdc++.h>
#define MOD 2000003
#define MN 1717171
#define int long long

using namespace std;
int n, m, k;
pair<int, int> P[MN];
map<pair<int, int>, int> Prec;
int FACT[MN];

int fp(int v, int e) {
    if(!e) return 1;
    if(e & 1) return v * fp(v * v % MOD, e/2) % MOD;
    return fp(v * v % MOD, e/2);
}
int inv(int v) {return fp(v, MOD-2);}
int comb(int n, int k) {
    if(k < 0 || n < 0 || k > n) return 0;
    return FACT[n] * inv(FACT[n-k]) % MOD * inv(FACT[k]) % MOD; 
}
int drumuri(int a, int b, int c, int d) {
    return comb(c - a + d - b, c - a);
}
int calcul(int l, int c) { //nrm de a ajunge in (l, c)
    if(Prec.count({l, c})) return Prec[{l, c}];
    int re = drumuri(1, 1, l, c);
    for(int i = 1; i <= k; ++i) {
        if(P[i].first <= l && P[i].second <= c && (P[i].first != l || P[i].second != c))
            re = (re - calcul(P[i].first, P[i].second) * drumuri(P[i].first, P[i].second, l, c) % MOD + MOD) % MOD;
    }
    Prec[{l, c}] = re;
   // printf("am calculat %d %d ca fiind %d\n", l, c, re);
    return re;
}
signed main() {
    freopen("padure2.in", "r", stdin);
    freopen("padure2.out", "w", stdout);
    scanf("%lld%lld%lld", &n, &m, &k);
    FACT[0] = 1;
    for(int i = 1; i < MN; ++i) FACT[i] = i * FACT[i-1] % MOD;
    int ok = 1;
    for(int i = 1; i <= k; ++i) {
        scanf("%lld%lld", &P[i].first, &P[i].second);
        if(P[i].first == 1 && P[i].second == 1) ok = 0;
        if(P[i].first == n && P[i].second == m) ok = 0;
    }
    if(!ok) {
        printf("%d\n", 0);
        return 0;
    }
    printf("%lld\n", calcul(n, m));
    return 0;
}