Cod sursa(job #1709477)

Utilizator lookingForAChallengeUBB Cociorva Popoveniuc Salajan lookingForAChallenge Data 28 mai 2016 12:29:23
Problema Padure2 Scor 100
Compilator cpp Status done
Runda ONIS 2016 - Runda - 2 - ACM ICPC Romanian Programming Contest Marime 2.09 kb
#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define ld long double
#define pb push_back
#define mp make_pair
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pdd pair<ld, ld>
#define all(x) (x).begin(), (x).end()
#define x first
#define y second

const int NMAX = 2000005;
const int QMAX = 1005;
const int MOD = 2000003;

int n, m, q;
int dp[2][QMAX];
int fact[NMAX], inv[NMAX];
pii p[QMAX];

int comb(int n, int k) {
    int ans = fact[n];
    ans = (1LL * ans * inv[k]) % MOD;
    ans = (1LL * ans * inv[n - k]) % MOD;
    return ans;
}

int ways(int a, int b, int c, int d) {
    int n = c - a;
    int m = d - b;
    return comb(n + m, n);
}

int lgpow(int a, int b, int mod) {
    int r = 1;

    for (int i = 0; (1LL << i) <= b; i++) {
        if ((1LL << i) & b)
            r = (1LL * r * a) % mod;
        a = (1LL * a * a) % mod;
    }

    return r;
}

int main() {
    cin.sync_with_stdio(false);

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

    cin >> n >> m >> q;

    for (int i = 1; i <= q; i++) {
        cin >> p[i].x >> p[i].y;
    }

    fact[0] = 1;
    for (int i = 1; i <= n + m; i++) {
        fact[i] = (1LL * fact[i - 1] * i) % MOD;
    }

    inv[0] = 1;
    inv[n + m] = lgpow(fact[n + m], MOD - 2, MOD);
    for (int i = n + m - 1; i > 0; i--) {
        inv[i] = (1LL * inv[i + 1] * (i + 1)) % MOD;
    }

    sort(p + 1, p + q + 1);

    int ans = ways(1, 1, n, m);
    for (int i = 1; i <= q; i++) {
        dp[1][i] = ways(1, 1, p[i].x, p[i].y);

        for (int j = 1; j < i; j++) {
            if (p[j].x <= p[i].x && p[j].y <= p[i].y) {
                for (int k = 0; k < 2; k++) {
                    int mlc = (1LL * dp[1 - k][j] * ways(p[j].x, p[j].y, p[i].x, p[i].y)) % MOD;
                    dp[k][i] = (dp[k][i] + mlc) % MOD;
                }
            }
        }

        int mlc = (1LL * dp[1][i] * ways(p[i].x, p[i].y, n, m)) % MOD;
        ans = (ans - mlc + MOD) % MOD;

        mlc = (1LL * dp[0][i] * ways(p[i].x, p[i].y, n, m)) % MOD;
        ans = (ans + mlc) % MOD;
    }

    cout << ans;

    return 0;
}