求交换次数的期望

链接: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

题意 : 在初始时你有一颗价值为 0 的宝石, 然后你有 n 个盒子,每个盒子都有一定的概率会开出宝石,每当你遇到更大的宝石,就会交换你手中的和盒子中的,求期望交换的次数。
思路分析 : 当面对第 i 个盒子时,如果要拿里面的宝石,那么前 i-1 个盒子中比第 i 个盒子中大的均没有出现,树状数组搞一下就行
代码示例 :
using namespace std;
#define ll long long
const ll maxn = 1e5+5;
const ll mod = 998244353;
const ll imod = 828542813;
const double eps = 1e-9;
const double pi = acos(-1.0);
const ll inf = 0x3f3f3f3f;

ll n;
struct node
{
    ll p, d;
    ll id;
    node(ll _p=0,ll _d=0,ll _id=0):p(_p),d(_d),id(_id){}
    bool operator< (const node &v){
        return d > v.d;
    }
};
vector<node>ve;
ll arr[maxn];
ll lowbit(ll x){return x&(-x); }
ll qw(ll x, ll cnt){
    ll res = 1;
    
    while(cnt){
        if (cnt&1) res *= x;
        res %= mod;
        x *= x;
        x %= mod;
        cnt >>= 1;
        //printf("---- %lld 
", res);
    }
    return res;
}

ll c[maxn];
void update(ll x, ll pos) {
    for(ll i = pos; i <= n; i += lowbit(i)){
        c[i] *= x;
        c[i] %= mod;
    }
}

ll query(ll pos){
    ll res = 1;
    
    for(int i = pos; i ; i -= lowbit(i)){
        res *= c[i];    
        res %= mod;
    }
    return res;
}

int main() {
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    ll p, d;
    
    cin >> n;
    //printf("+++ %lld
", qw(100, mod-2));
    for(ll i = 1; i <= n; i++){
        scanf("%lld%lld", &p, &d);
        ve.push_back(node(p, d, i));        
        arr[i] = d;
        c[i] = 1;
    }
    c[0] = 1;
    sort(ve.begin(), ve.end());
    ll ans = 0;
    for(ll i = 0; i < n; i++){  
        ll tem = query(ve[i].id-1);
        ans += (ve[i].p*imod%mod)*tem%mod;
        update((100-ve[i].p)*imod%mod, ve[i].id);
        ans %= mod;  
    }
    printf("%lld
", ans);
    return 0;
}
东北日出西边雨 道是无情却有情
原文地址:https://www.cnblogs.com/ccut-ry/p/9439016.html