https://www.nowcoder.com/acm/contest/143/F
Question meaning: give a path of n nodes, from 1 to n, each point has a certain probability to have a diamond with a value of w. if the diamond is larger than the diamond in hand, he will throw the previous one to choose this one. Hope to throw.
Analysis:
The probability of throwing each point is that the diamond larger than it has never appeared before.
Then we can maintain this probability through the line segment tree, using the prefix product.
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<iomanip>
using namespace std;
const int maxn = 1e5 + 12;
#define ll long long int
#define Build build
#define Node node
#define charmax(a,b) a=max(a,b)
#define charmin(a,b) a=min(a,b)
#define clr(a,b) memset(a,b,sizeof a)
#define mod 998244353
#define rmod 828542813
ll a[5*maxn];
//I'm very sorry for my friends and our team "goodbye".That's not my time to say goodbye.I'm back now! -Irish_Moonshine
struct node {
int x, id, pos;
bool operator < (const node &a) const {
if (x > a.x || x == a.x&&id < a.id) return 1;
return 0;
}
}s[2*maxn];
void Build(int l, int r, int x) {
int m;
if (l == r) { a[x] = 1; return; }
m = (l + r) / 2;
build(l, m, x * 2);
build(m + 1, r, x * 2 + 1);
a[x] = 1;
}
void update(int l, int r, int x, int A, int B) {
int m;
if (l == r) {
a[x] = 1ll * (100 - B)*rmod%mod; return;
}
m = (l + r) / 2;
if (A <= m) update(l, m, x * 2, A, B);
else update(m + 1, r, x * 2 + 1, A, B);
a[x] = a[x * 2] * a[x * 2 + 1] % mod;
}
ll query(int l, int r, int x, int A, int B) {
int m; ll ans = 1;
m = (l + r) / 2;
if (l >= A && r <= B) return a[x];
if (A <= m) ans = ans * query(l, m, x * 2, A, B) % mod;
if (B >= m + 1) ans = ans * query(m + 1, r, x * 2 + 1, A, B) % mod;
return ans;
}
ll qkm(ll a, ll b) {
ll ans = 1;
while(b > 0) {
if (b % 2) ans = ans * a%mod;
a = a * a%mod;
b /= 2;
}
return ans;
}
int main()
{
ll ans=0, n;
scanf("%lld", &n);
for (int i = 1; i <= n; i++) {
scanf("%d %d", &s[i].pos, &s[i].x);
s[i].id = i;
}
sort(s + 1, s + 1 + n);
Build(1, n, 1);
for (int i = 1; i <= n; i++) {
ans = (ans + query(1, n, 1, 1, s[i].id)*s[i].pos%mod*rmod) % mod;
update(1, n, 1, s[i].id, s[i].pos);
}
printf("%lld\n", ans);
return 0;
}