Cod sursa(job #1709219)

Utilizator team_nameUPB Banu Popa Visan team_name Data 28 mai 2016 11:20:37
Problema Padure2 Scor 0
Compilator cpp Status done
Runda ONIS 2016 - Runda - 2 - ACM ICPC Romanian Programming Contest Marime 1.73 kb
#include <cstdio>
#include <algorithm>
#include <vector>
#include <unordered_set>
#include <cassert>
#define x first
#define y second
#define MAXC 1005
#define MAXN 1000005
#define mod 2000003
using namespace std;

int n, m, c, dp[MAXC];
vector< pair<int, int> >  v;
int fact[2 * MAXN], ifact[MAXN];

int plog(int x, int pw) {
    if(!pw) return 1;
    int aux = plog(x, pw >> 1);

    return 1LL * aux * aux % mod * ((pw & 1)?x:1) % mod;
}

void precalc() {
    ifact[0] = fact[0] = 1;

    for(int i = 1; i < 2 * MAXN; ++i) {
        fact[i] = (1LL * fact[i - 1] * i) % mod;
        if(i < MAXN)
            ifact[i] = plog(fact[i], mod - 2);
    }
}

int ifactf(int x) {
    if(x < MAXN) return ifact[x];
    return plog(fact[x], mod - 2);
}

int comb(int n, int m) {
    return 1LL * fact[n] * ifactf(m) % mod * ifactf(n - m) % mod;
}

int main() {
    freopen("padure2.in", "r", stdin);
    freopen("padure2.out", "w", stdout);

    precalc();
    scanf("%d %d %d", &n, &m, &c);

    for(int i = 1; i <= c; ++i) {
        pair<int, int> a;
        scanf("%d %d", &a.x, &a.y);
        v.push_back(a);
        if(a.x == n && a.y == m)
            return 0 * printf("0\n");
    }

    v.push_back(make_pair(n, m));

    sort(v.begin(), v.end());
    v.resize(distance(v.begin(), unique(v.begin(), v.end())));

    c = (int) v.size();

    for(int i = 0; i < c; ++i) {
        dp[i] = comb(v[i].x + v[i].y - 2, v[i].x - 1);

        for(int j = 0; j < i; ++j) {
            if(v[j].first <= v[i].first && v[j].second <= v[i].second) {
                dp[i] = (dp[i] - 1LL * dp[j] * comb(v[i].x - v[j].x + v[i].y - v[j].y, v[i].x - v[j].x)) % mod;
                if(dp[i] < 0) dp[i] += mod;
            }
        }
    }

    printf("%d\n", dp[c - 1]);

    return 0;
}