1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #define int long long using namespace std; const int MAXN = 205; const int Mod = 110119;
int cnt, cas; int ans, n, m, sum, fac[Mod + 5], dp[Mod + 5];
struct node { int x, y; } s[MAXN];
int qpow(int x, int y) { int res = 1; while (y) { if (y & 1) res = res * x % Mod; x = x * x % Mod; y >>= 1; } return res; }
int C(int x, int y) { if (y > x) return 0; if (y == 0 || y == x) return 1; return fac[x] * qpow(fac[y], Mod - 2) % Mod * qpow(fac[x - y], Mod - 2) % Mod; }
int Lucas(int x, int y) { if (y == 0) return 1ll; return C(x % Mod, y % Mod) * Lucas(x / Mod, y / Mod) % Mod; }
int Dis(int p, int q) { int a = s[q].x - s[p].x, b = s[q].y - s[p].y; if ((2 * a - b) % 3 != 0 || (2 * b - a) % 3 != 0) return 0; int x = (2 * a - b) / 3; int y = (2 * b - a) / 3; if (x < 0 || y < 0) return 0; return Lucas(x + y, x); }
bool cmp(node a, node b) { return (a.x == b.x) ? a.y < b.y : a.x < b.x; }
signed main() {
fac[0] = 1; for (int i = 1; i < Mod - 1; i++) { fac[i] = fac[i - 1] * i % Mod; }
while (scanf("%lld %lld %lld", &n, &m, &cnt) != EOF) {
for (int i = 0; i <= cnt + 5; i++) { s[i].x = s[i].y = dp[i] = 0; }
for (int i = 1; i <= cnt; i++) { scanf("%lld %lld", &s[i].x, &s[i].y); } s[++cnt].x = 1, s[cnt].y = 1;
sort(s + 1, s + 1 + cnt, cmp);
ans = 0;
dp[1] = 1ll; for (int i = 2; i <= cnt; i++) { for (int j = 1; j < i; j++) { dp[i] = (dp[i] - Dis(j, i * dp[j] % Mod + Mod) % Mod; } }
s[++cnt].x = n, s[cnt].y = m;
for (int i = 1; i < cnt; i++) { ans = ((ans + dp[i] * Dis(i, cnt)) % Mod + Mod) % Mod; }
printf("Case #%lld: %lld\n", ++cas, ans);
}
return 0; }
|