Pagini recente » Clasament Teme ACM Unibuc 2013 | Cod sursa (job #2859153) | Cod sursa (job #2084938) | Cod sursa (job #3192798) | Cod sursa (job #1709244)
#include <fstream>
using namespace std;
const int NMAX = 1000000;
const int MOD = 2000003;
int ridica(int a, int b) {
if (!b)
return 1;
else if (b & 1)
return (1LL * a * ridica(a, b - 1)) % MOD;
else {
int aux = ridica(a, b >> 1);
return (1LL * aux * aux) % MOD;
}
}
int facts[2 * NMAX + 5];
int inv_facts[2 * NMAX + 5];
void precompute() {
facts[0] = 1;
for (int i = 1; i < 2 * NMAX; ++ i)
facts[i] = (1LL * i * facts[i - 1]) % MOD;
inv_facts[2 * NMAX - 1] = ridica(facts[2 * NMAX - 1], MOD - 2);
for (int i = 2 * NMAX - 2; i >= 0; -- i)
inv_facts[i] = ((i + 1LL) * inv_facts[i + 1]) % MOD;
}
int comb(int a, int b) {
return ((1LL * facts[a + b] * inv_facts[a]) % MOD * inv_facts[b]) % MOD;
}
const int CMAX = 1005;
int n, m, c;
struct Point {
int lin, col;
Point(int _lin = 0, int _col = 0): lin(_lin), col(_col) {}
} v[CMAX];
bool there_is(int lin, int col) {
for (int i = 1; i <= c; ++ i)
if (v[i].lin == lin && v[i].col == col)
return true;
return false;
}
bool operator<(const Point &a, const Point &b) {
return a.lin <= b.lin && a.col <= b.col;
}
int dp[CMAX];
bool vis[CMAX];
int compute(int node) {
if (vis[node])
return dp[node];
vis[node] = true;
dp[node] = comb(n - v[node].lin, m - v[node].col);
for (int i = 0; i <= c; ++ i)
if (i != node && v[node] < v[i])
dp[node] = (dp[node] + MOD - (1LL * compute(i) * comb(v[i].lin - v[node].lin, v[i].col - v[node].col)) % MOD) % MOD;
return dp[node];
}
int main()
{
ifstream cin("padure2.in");
ofstream cout("padure2.out");
cin >> n >> m >> c;
for (int i = 1; i <= c; ++ i)
cin >> v[i].lin >> v[i].col;
if (there_is(1, 1) || there_is(n, m)) {
cout << "0\n";
cin.close();
cout.close();
return 0;
}
precompute();
v[0].lin = 1;
v[0].col = 1;
cout << compute(0) << '\n';
cin.close();
cout.close();
return 0;
}