題目鏈接
題目大意
一共有n個箱子, 第 個箱子有 的概率開出大小爲 的鑽石。 初始玩家手裏有一個size爲0的鑽石, 且手裏最多只能有一個鑽石, 如果當前開的箱子中得到的鑽石大於手中的鑽石, 則替換, 問最終替換次數的期望是多少。 最終對答案模998244353。
數據範圍
解題思路
題意是讓求交換鑽石次數的期望, 因爲根據期望的性質 , 可以將問題轉換爲每個鑽石對次數期望的貢獻, 因爲每個鑽石最多隻能交換一次, 所以每個鑽石的貢獻就是這個鑽石被選中的概率 這個鑽石能貢獻的交換次數(1次), 也就是求每個鑽石被選中的概率和。
如果第 個鑽石要被選中, 那麼前 中 比他大的都不能出現, 其他小的無所謂, 所以對於第 個鑽石對答案的貢獻就是 .
所以每次需要求一個前綴乘積, 可以用樹狀數組或者線段樹解決。
因爲是維護乘積, 所以要將樹狀數組初始化爲1, 同時還需要考慮維護分數用逆元處理一下。
使用樹狀數組按照size大小從大到小排序, 那麼每次查詢的樹狀數組的前綴乘積都是比他大的數的乘積。
/********************************************
*Author* :ZZZZone
*Created Time* : 日 8/ 5 17:08:31 2018
* Ended Time* : 日 8/ 5 17:28:23 2018
*********************************************/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <stack>
using namespace std;
#define debug(x) std::cerr << #x << " = " << (x) << std::endl
typedef pair<int, int> PII;
typedef long long LL;
typedef unsigned long long ULL;
inline void OPEN(string s){
freopen((s + ".in").c_str(), "r", stdin);
freopen((s + ".out").c_str(), "w", stdout);
}
const int MAXN = 1e5;
const int Mod = 998244353;
struct Node{
int p, sz, id;
bool operator < (const Node& tmp) const{
return sz > tmp.sz || (sz == tmp.sz && id < tmp.id);
}
}a[MAXN+5];
LL bitsum[MAXN+5];
int n;
LL fast_pow(LL x, LL y){
LL res = 1LL;
while(y != 0){
if(y & 1) res =(res * x) % Mod;
y >>= 1;
x = (x * x) % Mod;
}
return res;
}
inline int lowbit(int x){return (x & (-x)); }
inline void Add(int p, LL x){
while(p <= n){
bitsum[p] = (bitsum[p] * x) % Mod;
p += lowbit(p);
}
}
inline LL Sigma(LL p){
LL res = 1LL;
while(p){
res = (res * bitsum[p]) % Mod;
p -= lowbit(p);
}
return res;
}
void Init(){
scanf("%d", &n);
for(int i = 1; i <= n; i++){
scanf("%d %d", &a[i].p, &a[i].sz);
a[i].id = i;
}
sort(a + 1, a + 1 + n);
for(int i = 0; i <= MAXN; i++) bitsum[i] = 1LL;
}
void Solve(){
LL ans = 0LL ,inv = fast_pow(100LL, Mod - 2);
for(int i = 1; i <= n; i++){
LL tmp = Sigma(a[i].id-1) * (LL)a[i].p % Mod * inv % Mod;
ans = (ans + tmp) % Mod;
Add(a[i].id, inv * (100LL - (LL)a[i].p) % Mod);
}
printf("%lld\n", ans);
}
int main()
{
Init();
Solve();
return 0;
}