「解题报告」ARC124F Chance Meeting
?这你评 3246?好弱智。
首先容易发现,两个人的路径只会相交在一条直线上,那么若干个交点就都在这一条直线上。
考虑容斥求这个问题,拿至少出现
如何统计至少出现
首先考虑交点数。考虑枚举交点
设
然后考虑相邻交点对数。这个相当于我们枚举两个点,然后需要保证这两个点中间不会有另外一个交点。发现这其实就是一个卡特兰数,那么答案其实就是
那么至少有
相邻三个交点对数也是同样的,我们选取两个点,要求这中间恰好有一个交点,这个方案数就是卡特兰数卷积一下,也很容易算,懒得写式子了。
然后就做完了,好弱智。
void pre(int n) {
fac[0] = 1;
for (int i = 1; i <= n; i++)
fac[i] = 1ll * fac[i - 1] * i % P;
inv[n] = qpow(fac[n], P - 2);
for (int i = n; i >= 1; i--)
inv[i - 1] = 1ll * inv[i] * i % P;
}
Polynomial f, g, c, d;
int main() {
pre(800000);
scanf("%d%d", &h, &w);
h--, w--;
f.set(w);
for (int i = 0; i <= w; i++) {
f[i] = 1ll * C(2 * i + h, h) * C(2 * i, i) % P;
}
g = f * f;
c.set(w);
c[0] = 1;
for (int i = 1; i <= w; i++) {
c[i] = (C(2 * i, i) - C(2 * i, i - 1) + P) % P;
}
d = c * c;
int ans = 0;
// at least 1: 1 - 2
ans = g[w];
for (int i = 0; i <= w - 1; i++) {
ans = (ans - 2ll * g[i] * c[w - 1 - i] % P + P) % P;
}
// at least 2: 2 - 3
for (int i = 0; i <= w - 1; i++) {
ans = (ans - 2ll * g[i] * c[w - 1 - i] % P + P) % P;
}
for (int i = 0; i <= w - 2; i++) {
ans = (ans + 4ll * g[i] * d[w - 2 - i] % P + P) % P;
}
ans = 1ll * ans * C(2 * h, h) % P;
printf("%d\n", ans);
return 0;
}