[Keyence2019] Paper Cutting
Paper Cutting
题面翻译
有一个 \((H+1)\times(W+1)\) 的网格,网格中有 \(H\) 条水平线和 \(W\) 条竖直线。
你需要执行 \(K\) 次操作,每次沿一条水平线或竖直线将网格切开。定义一次操作的权值为切割后网格被切分的块数。
定义一个操作序列的权值为 \(K\) 次操作的权值和。
求所有操作序列的权值之和,答案对 \(10^9+7\) 取模。
其中 \(1\leq H,W\leq 10^7\),\(1\leq K \leq H+W\),且 \(H,W,K\) 为整数。
Solution
考虑单次操作的贡献是什么,假设当前为第 \(t\) 次操作。考虑第 \(t\) 次操作为当前操作的操作序列个数,容易算出为:
\[t!(k-t)!\binom{H+W-t}{K-t}
\]
而这次操作的贡献为:
\[\sum\limits_{i=0}^t\binom{H}{i}\binom{W}{t-i}(i+1)(t-i+1)
\]
那么贡献即为:
\[t!(K-t)!\binom{H+W-t}{K-t}\sum\limits_{i=0}^t\binom{H}{i}\binom{W}{t-i}(i+1)(t-i+1)
\]
序列个数不难 \(\mathcal O(n)-\mathcal O(1)\) 计算,而贡献为 \(\mathcal O(n)\) 计算,考虑优化。
化式子:
\[\begin{array}{rll}
&&\displaystyle\sum\limits_{i=0}^t\binom{H}{i}\binom{W}{t-i}(i+1)(t-i+1)\\
&=&\displaystyle(t+1)\left(\sum\limits_{i=0}^t\binom{H}{i}\binom{W}{t-i}\right)+i(t-i)\left(\sum\limits_{i=0}^t\binom{H}{i}\binom{W}{t-i}\right)\\
\end{array}
\]
前半部分直接使用范德蒙德卷积,后半部分拆一下组合数:
\[\begin{array}{rll}
&=&\displaystyle(t+1)\binom{H+W}{t}+\sum\limits_{i=0}^t\dfrac{H!W!}{(i-1)!(H-i)!(t-i-1)!(W-t+1)!}\\
&=&\displaystyle(t+1)\binom{H+W}{t}+\sum\limits_{i=0}^t\dfrac{HW(H-1)!(W-1)!}{(i-1)!(H-i)!(t-i-1)!(W-t+1)!}\\
&=&\displaystyle(t+1)\binom{H+W}{t}+HW\sum\limits_{i=0}^t\binom{H-1}{i-1}\binom{W-1}{t-i-1}
\end{array}
\]
同样使用范德蒙德卷积可以得到:
\[\begin{array}{rll}
&=&\displaystyle(t+1)\binom{H+W}{t}+HW\binom{H+W-2}{t-2}
\end{array}
\]
显然可以 \(\mathcal O(n)-\mathcal O(1)\) 计算。
时间复杂度 \(\mathcal O(n)\)。
Code
int N, M, K;
mint fac[_N], ifac[_N];
void init(int n) {
fac[0] = 1; For(i, 1, n) fac[i] = fac[i-1] * i;
ifac[n] = 1 / fac[n]; Rof(i, n, 1) ifac[i-1] = ifac[i] * i;
}
mint binom(int x, int y) {
if (x < y || y < 0) return 0;
return fac[x] * ifac[y] * ifac[x-y];
}
void _() {
cin >> N >> M >> K; init(N + M);
mint ans = 0;
For(k, 1, K) {
mint tmp = fac[k] * fac[K - k] * binom(N + M - k, K - k);
tmp *= (k + 1) * binom(N + M, k) + binom(N + M - 2, k - 2) * N * M;
ans += tmp;
}
cout << ans << '\n';
}