2018牛客多校第五场 take (树状数组+期望)

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

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

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个宝箱,每个宝箱都有一个概率p打开之后其中有一颗钻石尺寸为d。现在从第一个宝箱开始依次打开,刚开始视作手中钻石尺寸为0,如果打开一个宝箱其中钻石的尺寸大于手中的钻石,就进行一次交换。问交换次数的期望。

思路:交换次数有很多种可能,一种种去算非常复杂。因为期望有可加性,也就是E(X+Y)=E(X)+E(Y)。所以所有交换次数的期望就等于单独每个宝箱能够打开后进行交换次数期望的和,单个宝箱交换次数要么为0,要么为1。所以一个宝箱能够产生交换次数的话就能对答案产生贡献,一个宝箱能够进行交换的话意味着在这个宝箱之前的那些宝箱当中,拥有着比当前宝箱更大尺寸钻石的宝箱打开后都没有钻石。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=998244353;
const int maxn=1e5+10;
int c[maxn];
struct node
{
    int d,id;
    ll p;
    bool operator<(const node &a)const
    {
        if(d==a.d) return id<a.id;
        return d>a.d;
    }
}q[maxn];

int lowbit(int x)
{
    return x&(-x);
}
void add(int p,ll v)
{
    while(p<=maxn)
    {
        c[p]=(c[p]*v)%mod;
        p+=lowbit(p);
    }
}

ll sum(int p)
{
    ll res=1;
    while(p)
    {
        res=(res*c[p])%mod;
        p-=lowbit(p);
    }
    return res;
}

ll quickpow(ll a,ll b,ll m)
{
    a=a%m;
    ll ans=1;
    while(b)
    {
        //printf("%d\n",++kase);
        if(b&1) ans=(ans*a)%mod;
        b>>=1;
        a=(a*a)%mod;
    }
    return ans;
}
int main()
{
    int n;
    scanf("%d",&n);
    ll inv=quickpow(100,mod-2,mod);
    for(int i=1;i<=maxn;i++) c[i]=1;
    for(int i=1;i<=n;i++)
    {
        scanf("%lld %d",&q[i].p,&q[i].d);
        q[i].p=(q[i].p*inv)%mod;
        q[i].id=i;
    }
    sort(q+1,q+n+1);
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
        ans=(ans+(1LL*sum(q[i].id)*q[i].p%mod))%mod;
        add(q[i].id,(1-q[i].p+mod)%mod);
    }
    printf("%lld\n",ans);
}

猜你喜欢

转载自blog.csdn.net/baymax520/article/details/81463321