ABC240G Teleporting Takahashi

考虑只考虑二维:

\(\sum \binom{x + y + 2k}{x+i,y + k - i,k - i}\\=\sum \binom{x+y+2k}{x+k}\times\binom{x+k}{x+i}\times\binom{y+k}{i}\)

即考虑枚举二维上如何操作,考虑其共走了\(x + y + 2k\)步,

先枚举第一维上的正方向,然后枚举第二维正方向的位置,然后枚举第二维回退的方向位置。

考虑 \(= \binom{x + y + 2k}{x+ k}\times \sum\binom{x+k}{x + i} \times \binom{y + k}{i} = \binom{x + y + 2k}{x + k} \times \binom{x + y + 2k}{x + y + k}\)

那么第三维的处理是简单的。

在化简过程中共使用了\(2\)次范德蒙德卷积

复杂度\(O(n)\)

点击查看代码
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const int N = 10000010, MOD = 998244353;
long long fac[N], inv[N], ans, n, X, Y, Z;
inline long long C (long long n, long long m) {
	if (n < m || n < 0 || m < 0) return 0;
	return fac[n] * inv[m] % MOD * inv[n - m] % MOD;
}
inline long long solve (long long n, long long m) {
	if (n < m || (n - m) & 1) return 0;
	return C(n, m + (n - m) / 2);
}
int main () {
	scanf("%lld%lld%lld%lld", &n, &X, &Y, &Z);
	fac[0] = fac[1] = inv[1] = inv[0] = 1;
	for (long long i = 2; i <= n; i ++) {
		fac[i] = i * fac[i - 1] % MOD;
		inv[i] = (MOD - MOD / i) * inv[MOD % i] % MOD;
	}
	for (long long i = 2; i <= n; i ++)
		inv[i] = inv[i] * inv[i - 1] % MOD;
	for (long long i = 0; i <= n; i ++) {
		long long x = X + Y, y = X - Y;
		ans = (ans + solve(i, x) * solve(i, y) % MOD * C(n, i) % MOD * solve(n - i, Z) % MOD) % MOD;
	}
	printf("%lld", ans);
	return 0;
}

附:
发现上面的做法太 \(dead-do\) 了。

这里给一个官方题解的精妙做法:

  • 先考虑第一维;
    易得出在一维上有:
    \(f_1(N,X) = \binom{N}{\frac{N + X}{2}}\)

  • 再考虑二维情况:
    考虑转变二维坐标系为:
    \((x,y) \to (x + y,x - y)\)
    那么发现四种操作分别为:
    \((x,y) \to (x + 1,y + 1)\)
    \((x,y) \to (x + 1,y - 1)\)
    \((x,y) \to (x - 1,y + 1)\)
    \((x,y) \to (x - 1,y - 1)\)

那么此时的好处就是 \(x,y\) 二维均解放了,那么\(f_2(N,X,Y) = f_1(N,X)f_1(N,Y)\).

  • 三维情况
    此时是简单的。
    只要考虑枚举\(X,Y\)两维用了多少即可。
posted @ 2022-04-06 17:46  fhq_treap  阅读(27)  评论(0编辑  收藏  举报