# BZOJ4767: 两双手【组合数学+容斥原理】

## Input

|Ax|,|Ay|,|Bx|,|By| <= 500, 0 <= n,Ex,Ey <= 500

4 4 1
0 1 1 0
2 3

40

## 思路

$dp_{i}$表示从原点到i不经过任何黑点的方案数，这样就可以枚举从原点到现在的第一个经过的黑点所对应的方案数

#include<bits/stdc++.h>

using namespace std;

typedef pair<int, int> pi;
const int Mod = 1e9 + 7;
const int N = 1e3 + 10;
const int M = 3e6 + 10;

int n, ex, ey, ax, ay, bx, by;
int inv[M], fac[M], dp[M];
pi p[N];

int add(int a, int b) {
return (a += b) >= Mod ? a - Mod : a;
}

int sub(int a, int b) {
return (a -= b) < 0 ? a + Mod : a;
}

int mul(int a, int b) {
return 1ll * a * b % Mod;
}

int fast_pow(int a, int b) {
int res = 1;
while (b) {
if (b & 1) res = mul(res, a);
b >>= 1;
a = mul(a, a);
}
return res;
}

int C(int a, int b) {
if (a < 0 || b < 0) return 0;
return mul(fac[a + b], mul(inv[b], inv[a]));
}

void init() {
fac[0] = inv[0] = 1;
for (int i = 1; i < M; i++) fac[i] = mul(fac[i - 1], i);
inv[M - 1] = fast_pow(fac[M - 1], Mod - 2);
for (int i = M - 2; i >= 1; i--) inv[i] = mul(inv[i + 1], i + 1);
}

pi calc(int x, int y) {
int a = -1, b = -1;
if ((x * by - y * bx) % (ax * by - ay * bx) == 0)
a = (x * by - y * bx) / (ax * by - ay * bx);
if ((x * ay - y * ax) % (bx * ay - by * ax) == 0)
b = (x * ay - y * ax) / (bx * ay - by * ax);
return pi(a, b);
}

int main() {
#ifdef dream_maker
freopen("input.txt", "r", stdin);
#endif
init();
scanf("%d %d %d %d %d %d %d", &ex, &ey, &n, &ax, &ay, &bx, &by);
int cnt = 0;
p[++cnt] = calc(ex, ey);
if (p[1].first < 0 || p[1].second < 0) {
puts("0");
return 0;
}
for (int i = 1; i <= n; i++) {
int u, v; scanf("%d %d", &u, &v);
pi cur = calc(u, v);
if (cur.first < 0 || cur.second < 0 || cur.first > p[1].first || cur.second > p[1].second) continue;
//需要特判  cur.first > p[1].first || cur.second > p[1].second
p[++cnt] = cur;
}
n = cnt;
sort(p + 1, p + cnt + 1);
n = unique(p + 1, p + cnt + 1) - p - 1;
for (int i = 1; i <= n; i++) {
dp[i] = C(p[i].first, p[i].second);
for (int j = 1; j < i; j++) {
dp[i] = sub(dp[i], mul(dp[j], C(p[i].first - p[j].first, p[i].second - p[j].second)));
}
}
printf("%d", dp[n]);
return 0;
}

posted @ 2018-12-07 20:43  Dream_maker_yk  阅读(266)  评论(1编辑  收藏  举报