题目描述
Takuru 是一名能力者,他在地震时获得了念力致动的能力。所以他经常用自己的能力去干一些奇奇怪怪的事情。
有一天他获得了一张 nn 个点的无向完全图,之后他使用了能力,导致这张图的 \frac{n(n-1)}{2}2n(n−1) 条边中的每一条都有 \frac{x}{y}yx 的概率遭到破坏而消失。
现在 Takuru 想知道这张无向图点集的全部 2^n2n 个的子集中,是独立集的子集数量的期望值。
一张无向图 GG 的一个子集是独立集的定义如下:此点集 SS,满足对于任意的 x, y \in Sx,y∈S,图 GG 中不存在连接 xx 和 yy 的边。(空集也是一个合法的独立集)
输入描述
一行三个整数 nn,xx 和 yy (1 \leqslant n \leqslant 10^51⩽n⩽105,1 \leqslant x \leqslant y < 9982443531⩽x⩽y<998244353)。
输出描述
输出一个整数,用如下方式计算:
这张图独立集数量的期望可以写成一个最简分数 \frac{X}{Y}YX,那么你需要输出一个整数 pp,满足 0\leqslant p <9982443530⩽p<998244353 且 pY \equiv X \pmod {998244353}pY≡X(mod998244353)。保证合法的 pp 存在且唯一。
样例输入 1
3 1 2
样例输出 1
374341638
分析:考虑独立子集的定义,一定是这个点集中所有的点都不相连,除此外的边是无所谓的,所以直接计算每种子集对ans的贡献即可。
#include "bits/stdc++.h"
using namespace std;
const int mod = 998244353;
long long qk(long long a, long long n) {
long long ans = 1;
while (n) {
if (n & 1)ans = ans * a % mod;
n >>= 1;
a = a * a % mod;
}
return ans;
}
long long fac[100004];
void init() {
fac[0] = 1;
fac[1] = 1;
for (int i = 2; i < 100004; ++i) {
fac[i] = fac[i - 1] * i % mod;
}
}
long long c(long long a, long long b) {
return fac[a] * qk(fac[b], mod - 2) % mod * qk(fac[a - b], mod - 2) % mod;
}
int main() {
init();
int n, x, y;
cin >> n >> x >> y;
long long ans = 0;
for (long long i = 0; i <= n; ++i) {
if (i == 0){
ans += 1;
continue;
}
if (i == 1){
ans += n;
continue;
}
ans = (ans + c(n, i) * qk(x, i * (i - 1) / 2) % mod * qk(qk(y, i * (i - 1) / 2), mod - 2) % mod) % mod;
}
printf("%lld\n",ans);
}