标签:组合数 答案 code ons main register names 转移 template
题意简述:有\(n\)个桶和\(2n-1\)个球,每个桶最多能装一个球,且第\(i\)个桶可以装前\(2i-1\)个球。问取\(m\)个桶和\(m\)个球,并将每个球放进一个桶里的方案数,\(q\)组询问。\(1\leq q\leq 10^5, 1\leq m\leq n\leq 10^7\)。
有一个显然的\(O(nm)\)dp:设\(f_{i, j}\)为前\(i\)个桶选了\(j\)个桶的方案数,考虑转移:
若第\(i\)个桶不选,则\(f_{i-1, j}\Rightarrow f_{i, j}\)。
若第\(i\)个桶选,则前\(2i-1\)个球中有\(j-1\)个已经被选,剩余的可以自由选择,即\(f_{i-1, j-1}\cdot (2i-j)\Rightarrow f_{i, j}\)。
然后我们就可以打表啦!
观察发现\(f_{n, m}=\binom{n}{m}^2\cdot m!\),但是这个结论需要证明。
由这个式子不难想到,\(n\times n\)的棋盘中放\(m\)个无标号的互不攻击的车也是这个方案数,证明可以设\(g_{i, j}\)为\(i\times i\)的棋盘放\(j\)个车的方案数,考虑棋盘第\(n\)行、列(记为\(S\))的情况:
\(S\)中无车:显然答案为\(g_{n-1, m}\)。
\(S\)中有一个车:考虑剩下的\((n-1)\times(n-1)\)的棋盘,显然方案数为\(g_{n-1, m-1}\),且剩余的能放车的位置有\(2n-2m+1\)个。
\(S\)中有两个车:考虑一个\(g_{n-1, m-1}\)的情况,对于其中任意一种方案,我们均可以从\(m-1\)个车中选出一个\((x, y)\),将它拆成\((x, n)\)和\((n, y)\)的两个车,显然这样的方案是一一对应的。
因此\(g_{i, j}=g_{i-1, j}+(2i-j) g_{i-1, j-1}\),发现与\(f\)的递推式完全一致。所以这个到底是怎么想到的啊
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>
#define R register
#define ll long long
using namespace std;
const int N = 10010000, T = 110000, mod = 998244353;
int t, que[T][2], maxN;
ll fac[N], inv[N];
template <class T> inline void read(T &x) {
x = 0;
char ch = getchar(), w = 0;
while (!isdigit(ch)) w = (ch == '-'), ch = getchar();
while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
x = w ? -x : x;
return;
}
inline ll quickpow(ll base, ll pw) {
ll ret = 1;
while (pw) {
if (pw & 1) ret = ret * base % mod;
base = base * base % mod, pw >>= 1;
}
return ret;
}
int main() {
read(t);
for (R int i = 1; i <= t; ++i)
read(que[i][0]), read(que[i][1]), maxN = max(maxN, que[i][0]);
fac[0] = 1;
for (R int i = 1; i <= maxN; ++i)
fac[i] = fac[i - 1] * i % mod;
inv[maxN] = quickpow(fac[maxN], mod - 2);
for (R int i = maxN - 1; ~i; --i)
inv[i] = inv[i + 1] * (i + 1) % mod;
for (R int i = 1; i <= t; ++i) {
int x = que[i][0], y = que[i][1];
printf("%lld\n", fac[x] * fac[x] % mod * inv[y] % mod * inv[x - y] % mod * inv[x - y] % mod);
}
return 0;
}
标签:组合数 答案 code ons main register names 转移 template
原文地址:https://www.cnblogs.com/suwakow/p/11680135.html