题解 | #小䓤的质因数#
小䓤的质因数
https://ac.nowcoder.com/acm/problem/222910
D
简单的概率期望题。
考虑把问题抽象成有 个牌堆,第 个牌堆有 张牌,每次随机两个牌堆转移一张牌 ,其中 任选。
然后分别计算出无穷次操作之后哪个牌堆会拥有最后的 张牌的概率,再乘上它的贡献就好了。
考虑如何计算这个概率,首先扔一个结论:
- 当只有两堆牌的时候,一堆是 ,一堆是 ,其中 留下来的概率是 。
简单证明一下这个结论,设 表示剩 张牌时,这堆能活着留下来不死的概率:
- :剩 张牌游戏结束,死得彻底。
- :剩 张,就是把对方“掏空”了, 存活。
- :关键的式子,其实也好懂,剩 张牌时无非两种转移的方向,要么自己少一张(被别人拿走),要么自己多一张(拿走别人的),两种情况出现的概率相同,加起来求平均就是答案。
然后把最后一个式子稍微变换一下,得到:
这啥玩意?一看就知道是等差数列的形式!(连续三项 满足 !)
所以对于等差数列而言, 不就显然了么!
知道了上面这些东西之后,第 个质因子的贡献显然就是:
( 表示所有 的和)
左边是概率,右边是贡献,乘一块就是它的期望啦!
最后给每个数的贡献的期望求个和,这道题就做完了
#include<cstdio>
#define int long long
int init(){
char c = getchar();
int x = 0, f = 1;
for (; c < '0' || c > '9'; c = getchar())
if (c == '-') f = -1;
for (; c >= '0' && c <= '9'; c = getchar())
x = (x << 1) + (x << 3) + (c ^ 48);
return x * f;
}
void print(int x){
if (x < 0) x = -x, putchar('-');
if (x > 9) print(x / 10);
putchar(x % 10 + '0');
}
const int N = (int) 1e6 + 5, Mod = 998244353;
int p[N], c[N];
int quick_mod(int a, int b){
int s = 1; a %= Mod;
while (b) {
if (b & 1) s = s * a % Mod;
a = a * a % Mod; b >>= 1;
}
return s;
}
void Relax(int&a, int b){
a = a + b >= Mod ? a + b - Mod : a + b;
}
signed main(){
int n = init(), sum = 0;
for (int i = 1; i <= n; ++i)
p[i] = init(), sum += (c[i] = init());
int ans = 0, inv = quick_mod(sum, Mod - 2);
for (int j = 1; j <= n; ++j)
Relax(ans, c[j] * inv % Mod * quick_mod(p[j], sum) % Mod);
print(ans), putchar('\n');
}