# [BZOJ4767]两双手

[BZOJ4767]两双手

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

4 4 1
0 1 1 0
2 3

40

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;

int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
}

#define maxn 510
#define maxl 500010
#define MOD 1000000007
#define LL long long

struct Vec {
int x, y;

Vec() {}
Vec(int _, int __): x(_), y(__) {}

int operator ^ (const Vec& t) const { return x * t.y - y * t.x; }

bool operator < (const Vec& t) const { return x != t.x ? x < t.x : y < t.y; }
} A, B, ps[maxn], End, sol[maxn];
Vec trans(Vec a, Vec b, Vec p) {
if((p ^ b) % (a ^ b)) return Vec(-233, -233);
int x = (p ^ b) / (a ^ b);
if(!b.x || (p.x - a.x * x) % b.x) {
if(!b.y || (p.y - a.y * x) % b.y) return Vec(-233, -233);
return Vec(x, (p.y - a.y * x) / b.y);
}
return Vec(x, (p.x - a.x * x) / b.x);
}

int n, cnt;

void gcd(LL a, LL b, LL& x, LL& y) {
if(!b){ x = 1; y = 0; return ; }
gcd(b, a % b, y, x); y -= a / b * x;
return ;
}
LL Inv(LL a) {
LL x, y;
gcd(a, MOD, x, y);
return (x % MOD + MOD) % MOD;
}

LL fact[maxl], ifact[maxl];
void init() {
fact[0] = 1;
for(int i = 1; i < maxl; i++) fact[i] = fact[i-1] * i % MOD;
ifact[0] = 1;
for(int i = 1; i < maxl; i++) ifact[i] = ifact[i-1] * Inv(i) % MOD;
return ;
}
LL C(int a, int b) {
return (fact[a] * ifact[a-b] % MOD) * ifact[b] % MOD;
}

LL f[maxn];

int main() {
for(int i = 1; i <= n; i++) ps[i].x = read(), ps[i].y = read();

End = trans(A, B, End);
if(End.x < 0 || End.y < 0) return puts("0"), 0;
for(int i = 1; i <= n; i++) {
ps[i] = trans(A, B, ps[i]);
if(ps[i].x >= 0 && ps[i].y >= 0) sol[++cnt] = ps[i];
}
sort(sol + 1, sol + cnt + 1);

init();
sol[++cnt] = End;
for(int i = 1; i <= cnt; i++) {
f[i] = C(sol[i].x + sol[i].y, sol[i].x);
LL sum = 0;
for(int j = 1; j < i; j++) if(sol[j].x <= sol[i].x && sol[j].y <= sol[i].y)
(sum += f[j] * C(sol[i].x + sol[i].y - sol[j].x - sol[j].y, sol[i].x - sol[j].x) % MOD) %= MOD;
f[i] = (f[i] - sum + MOD) % MOD;
}

printf("%lld\n", f[cnt]);

return 0;
}


posted @ 2017-03-08 21:21  xjr01  阅读(212)  评论(0编辑  收藏  举报