Cod sursa(job #1709193)

Utilizator team_nameUPB Banu Popa Visan team_name Data 28 mai 2016 11:13:20
Problema Padure2 Scor 0
Compilator cpp Status done
Runda ONIS 2016 - Runda - 2 - ACM ICPC Romanian Programming Contest Marime 1.75 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;
vector<int> G[MAXC];
int fact[2 * MAXN];

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

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

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;
}

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

int comb(int n, int m) {
    assert(m <= n && m >= 0);
    return 1LL * fact[n] * ifact(m) % mod * ifact(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 = 1; i < c; ++i)
        for(int j = 0; j < i; ++j)
            if(v[j].first <= v[i].first && v[j].second <= v[i].second)
                G[i].push_back(j);

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

        for(auto b: G[i]) {
            dp[i] = (dp[i] - 1LL * dp[b] * comb(v[i].x - v[b].x + v[i].y - v[b].y, v[i].x - v[b].x)) % mod;
            if(dp[i] < 0) dp[i] += mod;
        }
    }

    assert(v[c - 1] == make_pair(n, m));
    printf("%d\n", dp[c - 1]);

    return 0;
}