求交换次数的期望
链接: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 \n", 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\n", 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\n", ans); return 0; }
东北日出西边雨 道是无情却有情