牛客多校第五场 F take 期望转化成单独事件概率(模板) 树状数组

链接:https://www.nowcoder.com/acm/contest/143/F
来源:牛客网

Kanade has n boxes , the i-th box has p[i] probability to have an diamond of d[i] size.

At the beginning , Kanade has a diamond of 0 size. She will open the boxes from 1-st to n-th. When she open a box,if there is a diamond in it and it's bigger than the diamond of her , she will replace it with her diamond.

Now you need to calculate the expect number of replacements.

You only need to output the answer module 998244353.

Notice: If x%998244353=y*d %998244353 ,then we denote that x/y%998244353 =d%998244353

输入描述:

The first line has one integer n.

Then there are n lines. each line has two integers p[i]*100 and d[i].

输出描述:

Output the answer module 998244353

示例1

输入

复制
3
50 1
50 2
50 3

输出

复制
499122178

备注:

1<= n <= 100000

1<=p[i]*100 <=100

1<=d[i]<=10^9

题意:有 n 个箱子,第 i 个箱子有 p[i] 的概率出现大小为 d[i] 的钻石 现在 小A 一开始手里有一个大小为 0 的钻石,他会根据 i 从小到大打开箱子, 如果箱子里有钻石且比小 A 手中的大,那么小 A 就会交换手中的钻石和箱子里 的钻石 求期望的交换次数
分析:求所有交换次数的期望,可以考虑从每次交换的钻石的角度。
   要求的期望是每次交换的概率的累加和,而每次交换都是因为遇到更大的钻石(这时才会产生有效的概率)
   所以我们要计算的每次交互的期望可以转换成每种钻石被打开的概率,而每种钻石要打开的概率就是其自身打开的概率乘以所有比他大的钻石不打开的概率
   这些钻石的概率和就是我们要求的期望
AC代码:
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <string>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
#define ls (r<<1)
#define rs (r<<1|1)
#define debug(a) cout << #a << " " << a << endl
using namespace std;
typedef long long ll;
const ll maxn = 1e5 + 10;
const ll mod = 998244353;
struct node {
    ll p, w, id;
};
node a[maxn];
ll A[maxn];
bool cmp( node x, node y ) {
    if( x.w == y.w ) {
        return x.id < y.id;
    }
    return x.w > y.w;
}
ll qow( ll a, ll b ) {
    ll ans = 1;
    while(b) {
        if( b&1 ) {
            ans = ans*a%mod;
        }
        a = a*a%mod;
        b /= 2;
    }
    return ans;
}
void add( ll x, ll n, ll y ) {
    while( x <= n ) {
        A[x] = A[x]*y%mod;
        x += x&(-x);
    }
}
ll ask( ll x ) {
    ll ans = 1;
    while(x) {
        ans = ans*A[x]%mod;
        x -= x&(-x);
    }
    return ans;
}
int main() {
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    ll inv = qow(100,mod-2);
    ll n;
    cin >> n;
    for( ll i = 1; i <= n; i ++ ) {
        cin >> a[i].p >> a[i].w;
        a[i].id = i;
    }
    sort( a+1, a+n+1, cmp );
    for( ll i = 1; i <= n; i ++ ) {
        A[i] = 1;
    }
    ll ans = 0;
    for( ll i = 1; i <= n; i ++ ) {
        ans += ask(a[i].id-1)*a[i].p%mod*inv%mod;
        ans %= mod;
        add(a[i].id,n,(100-a[i].p)*inv%mod);
    }
    cout << ans << endl;
    return 0;
}

  



猜你喜欢

转载自www.cnblogs.com/l609929321/p/9416257.html