Loading

P7592 数树(2021 CoE-II E)

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';
}
posted @ 2021-05-11 19:41  zzctommy  阅读(142)  评论(0编辑  收藏  举报