牛客17412 take 树状数组+概率统计

题目链接: 牛客17412 take

题目描述

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

题意:

有n个盒子,每个盒子有p概率使得盒子里面有一个大小为d的钻石,每次遇到遇到比你手中更大的钻石你需要进行交换。现在你可以从第1个盒子开始,一直任意选到第n个,求交换次数的期望值是多少。

题解:

每个盒子的概率p的乘100后的值,考虑到大数,就可以考虑用乘法逆元
对于期望高中已学过E(X+Y)=E(X)+E(Y),过求所以交换次数的期望值就是求各个点的期望值之和。
选到第i个盒子的前提是第1,2,3…i-1的盒子都没有打开,故可以严格按照盒子的下标,对1-p维护一个概率树状数组,需要了解的是概率是相乘,不是相加。

#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define ll long long
#define endl  '\n'
using namespace std;
const int mod=998244353;
ll n,tree[100005];
struct TREE
{
	ll p,d,id;
	bool operator <(const TREE &a)const
	{
		if(d==a.d)return id<a.id;
		return d>a.d;
	}
}a[100005];
void init(ll n)
{
	for(ll i=0;i<=n;i++)
	tree[i]=1;
}
int lowbit(ll x)
{
	return x&-x;
}
void add(ll i,ll x)
{
	while(i<=n)
	{
		tree[i]=(tree[i]*x)%mod;
		i+=lowbit(i);
	}
}
ll sum(ll i)
{
	ll res=1;
	while(i>0)
	{
		res=(tree[i]*res)%mod;
		i-=lowbit(i);
	}
	return res;
}
ll qpow(ll x,ll y,ll mod)
{
	ll res=1;
	while(y)
	{
		if(y&1)res=(res*x)%mod;
		x=(x*x)%mod;
		y>>=1;
	}
	return res;
}
int main()
{
    ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);
  	cin>>n;
  	init(n);
 	ll div=qpow(100,mod-2,mod),ans=0;
	for(ll i=1;i<=n;i++)
	{
		cin>>a[i].p>>a[i].d;
		a[i].p=(a[i].p*div+mod)%mod;
		a[i].id=i;
	}
  	sort(a+1,a+1+n);
  	for(ll i=1;i<=n;i++)
  	{
  		ans+=(sum(a[i].id)*a[i].p)%mod;
		add(a[i].id,(1-a[i].p+mod)%mod);	
	}
	cout<<(ans+mod)%mod;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值