F.take
题意:
有n个盒子,每个盒子有pi的概率有一颗大小为di的钻石。初始时有一颗大小为0的钻石,从小到大开盒子,每开到比当前钻石大的钻石就会交换一次。求交换次数的期望值。
题解:
求出每个盒子的期望值,最终求和。用树状数组维护每个盒子前面比他大的钻石的(1-pi)的积
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+10;
const int mod = 998244353;
int n;
int ans;
int id[N];
int tre[N];
struct node {
int p, d;
}a[N];
void add(int pos, int val) {
while(pos > 0) {
tre[pos] = (1ll*tre[pos]*val)%mod;
pos -= pos&(-pos);
}
}
int sum(int pos) {
int res = 1;
while(pos <= n) {
res = (1ll*res*tre[pos])%mod;
pos += pos&(-pos);
}
return res;
}
ll quick_mod(int n, int m) {
int res = 1, t = n;
while(m) {
if(m & 1) res = (1ll * res * t) % mod;
t = (1ll * t * t) % mod;
m >>= 1;
}
return res;
}
int main() {
scanf("%d", &n);
int inv = quick_mod(100, mod-2);
for(int i = 1; i <= n; i++) {
scanf("%d%d", &a[i].p, &a[i].d);
id[i] = a[i].d;
tre[i] = 1;
}
sort(id + 1, id + n + 1);
for(int i = 1; i <= n; i++) {
int p = lower_bound(id+1, id+n+1, a[i].d)-id;
ans += (1ll * sum(p+1) * a[i].p % mod) * inv % mod;
ans %= mod;
add(p, 1ll*(100-a[i].p)*inv%mod);
}
printf("%d\n", ans);
}