ACR135 C - Split and Maximize
题意
把一个长度为\(2n\)的排列分为等长的两部分\(A\)和\(B\)(不要求连续),这种划分的价值为\(\displaystyle\sum_{i=1}^{N}A_i\ B_i\), 一个排列的得分为所有所有划分方案中最大价值. 设长为\(2n\)的所有排列最大得分为\(M\), 问有多少中排列得分为\(M\).
\(n \leq 200000\)
题解
一道不错的计数题.
首先有一个显然的结论,就是当所有\(2i - 1\) 和\(2i\)在一起时, 这个排列一定为最大.
我们可以考虑每对数更靠左的一个数组成的长为\(n\)的序列, 有\(2^n \times n!\)种情况(因为每对\(2i\)和\(2i-1\)有一个属于这个序列)
考虑假设每对数较前的数已定, 那么只要在后面补上这对数的另一个就可以了. 因为补的顺序已定, 所以这就是一个卡特兰数.
因此最后公式就是$$2^n \times \frac{(2n)!}{n!}$$
在计数的时候如果较复杂,可以考虑钦定思想
代码
点击查看代码
#include <stdio.h>
#define LL long long
const LL Mod = 998244353ll;
const int N = 2e5;
int n; LL fac[N + 5], ifac[N + 5];
LL pow(LL x, LL y) {
LL res = 1;
while(y) {
if (y & 1)
res = res * x% Mod;
x = x * x % Mod;
y >>= 1;
}
return res;
}
int main() {
// freopen("t.in", "r", stdin);
scanf("%d", &n);
LL ans = pow(2, n);
for(int i = n + 2; i <= 2 * n; ++i)
ans = ans * i % Mod;
printf("%lld\n", ans);
return 0;
}