P7592 数树(2021 CoE-II E)
orz Macesuted!
设总方案数为 \(F\),总权值和为 \(G\)。显然有:
\[F(x)=x(1+F^{k_1}(x)+F^{k_2}(x))\\G(x,y)=x+xy^aG^{k_1}(x)+xy^{b}G^{k_2}(x)\\
\]
\[F(x)=x(1+F^{k_1}(x)+F^{k_2}(x))\\\dfrac{F(x)}{1+F^{k_1}(x)+F^{k_2}(x)}=x\\lF(x)=\dfrac{x}{1+x^{k_1}+x^{k_2}}
\]
普通拉反:
\[[x^n]F(x)=\frac{1}{n}[x^{-1}]lF^{-n}(x)\\=\frac{1}{n}[x^{n-1}](\frac{lF(x)}{x})^{-n}\\
\]
\[[x^n]F(x)=\frac{1}{n}[x^{n-1}](1+x^{k_1}+x^{k_2})^n\\
\]
枚举几个括号选了 \(x^{k_1}\) 即可计算,这时候 \(k_2\) 是定值。
\[G(x,y)=x+xy^aG^{k_1}(x,y)+xy^{b}G^{k_2}(x,y)\\\dfrac{G}{1+y^aG^{k_1}+y^bG^{k_2}}=x\\lG(x,y)=\dfrac{x}{1+y^ax^{k_1}+y^bx^{k_2}}\\
\]
\[[x^n]G(x)=\frac{1}{n}[x^{n-1}](1+y^ax^{k_1}+y^bx^{k_2})^n
\]
要求的是 \(\sum_{i=0}i[x^{n-1}y^i]G\) 。在 \(y\) 这一维求偏导,然后把 \(y=1\) 带进去求值就好了。
\[[x^{n-1}](1+y^ax^{k_1}+y^bx^{k_2})^{n-1}(ay^{a-1}x^{k_1}+by^{b-1}x^{k_2})\\
\]
所以答案就是
\[[x^{n-1}](1+x^{k_1}+x^{k_2})^{n-1}(ax^{k_1}+bx^{k_2})
\]
枚举一下后面的括号选了啥就和前面一样了。
顺便,如果您读到了这篇文章,能不能给点系统讲解微积分的文章啊/kel 我现在连偏导和积分的符号都不会用,百度到的都没有适合的……
#include <bits/stdc++.h>
using namespace std;
typedef double db;
typedef long long LL;
#define fi first
#define se second
#define pb push_back
#define mkp make_pair
#define sz(v) (int)(v).size()
#define rep(i, x, y) for(int i = x, i##end = y; i <= i##end; ++i)
#define per(i, x, y) for(int i = x, i##end = y; i >= i##end; --i)
template<class T> inline bool ckmax(T &x, T y) { return x < y ? x = y, 1 : 0; }
template<class T> inline bool ckmin(T &x, T y) { return x > y ? x = y, 1 : 0; }
inline int read() {
int x = 0, f = 1; char ch = getchar();
while(!isdigit(ch)) { if(ch == '-') f = 0; ch = getchar(); }
while(isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
return f ? x : -x;
}
const int N = 10000005;
const int mod = 998244353;
inline int qpow(int n, int k) {
int res = 1;
for(; k; k >>= 1, n = (LL)n * n % mod)
if(k & 1) res = (LL)res * n % mod;
return res;
}
int k1, k2, n, a, b;
int fac[N], ifc[N];
inline int comb(int n, int m) { return (LL)fac[n] * ifc[m] % mod * ifc[n - m] % mod; }
inline void init(const int &n = N - 1) {
fac[0] = 1;
for(int i = 1; i <= n; ++i) fac[i] = (LL)i * fac[i - 1] % mod;
ifc[n] = qpow(fac[n], mod - 2);
for(int i = n - 1; i >= 0; --i) ifc[i] = (LL)(i + 1) * ifc[i + 1] % mod;
}
inline int calc(int n, int m) {//[x ^ m] (1 + x ^ {k_1} + x ^ {k_2}) ^ n
int res = 0;
for(int i = 0; i * k1 <= m; ++i) if((m - i * k1) % k2 == 0)
res = (res + (LL)comb(n, i) * comb(n - i, (m - i * k1) / k2) % mod) % mod;
return res;
}
signed main() {
cin >> k1 >> k2 >> n >> a >> b, init();
cout <<
(LL)n * ((LL)a * calc(n - 1, n - 1 - k1) % mod + (LL)b * calc(n - 1, n - 1 - k2) % mod) % mod *
qpow(calc(n, n - 1), mod - 2) % mod << '\n';
}
路漫漫其修远兮,吾将上下而求索