pushdown 里面修改 tag[ls[x]] 的几行,注释了就不RE,不注释就RE,但是我空间也没看出越界的,自测数据也没RE
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 3e5 + 5, MOD = 998244353;
const int M = 6e6 + 5;
int n;
int l[N] = {}, r[N] = {};
int p[N] = {}, a[N] = {};
int cur = 0;
map<int, int> mp;
int rev[N];
ll fpow(ll a, ll b, ll p) {
ll mul = 1;
while (b) {
if (b & 1)
mul = mul * a % p;
a = a * a % p;
b >>= 1;
}
return mul;
}
ll inv10000;
struct SegmentTree {
int n = 0;
int rt[N];
int ls[M], rs[M], val[M], tag[M];
int newNode() {
n++;
ls[n] = rs[n] = val[n] = 0;
tag[n] = 1;
return n;
}
void pushup(int x) {
val[x] = (1ll * val[ls[x]] + val[rs[x]]) % MOD;
}
void pushdown(int x) {
if (tag[x] == 1)
return ;
if (!ls[x])
ls[x] = newNode();
if (!rs[x])
rs[x] = newNode();
val[ls[x]] = 1ll * val[ls[x]] * tag[x] % MOD;
val[rs[x]] = 1ll * val[rs[x]] * tag[x] % MOD;
tag[ls[x]] = 1ll * tag[ls[x]] * tag[x] % MOD;
tag[rs[x]] = 1ll * tag[rs[x]] * tag[x] % MOD;
tag[x] = 1;
}
void mdf(int &x, int lx, int rx, int p, int v) {
if (x == 0)
x = newNode();
if (lx + 1 == rx) {
val[x] = v;
return ;
}
int m = (lx + rx) / 2;
pushdown(x);
if (p < m)
mdf(ls[x], lx, m, p, v);
else
mdf(rs[x], m, rx, p, v);
pushup(x);
}
int mrg(int Lrt, int Rrt, int L1, int R1, int L2, int R2, int p) {
// printf("mrg:%d %d [%d,%d][%d,%d]\n", Lrt, Rrt, L1, R1, L2, R2);
if (!Lrt && !Rrt)
return 0;
if (!Rrt) {
tag[Lrt] = 1ll * tag[Lrt] * (1ll * p * L2 % MOD + 1ll * (MOD + 1 - p) * R2 % MOD) % MOD;
val[Lrt] = 1ll * val[Lrt] * (1ll * p * L2 % MOD + 1ll * (MOD + 1 - p) * R2 % MOD) % MOD;
return Lrt;
}
if (!Lrt) {
tag[Rrt] = 1ll * tag[Rrt] * (1ll * p * L1 % MOD + 1ll * (MOD + 1 - p) * R1 % MOD) % MOD;
val[Rrt] = 1ll * val[Rrt] * (1ll * p * L1 % MOD + 1ll * (MOD + 1 - p) * R1 % MOD) % MOD;
return Rrt;
}
int tmp[5];
tmp[1] = val[ls[Lrt]];
tmp[2] = val[rs[Lrt]];
tmp[3] = val[ls[Rrt]];
tmp[4] = val[rs[Rrt]];
pushdown(Lrt);
pushdown(Rrt);
ls[Lrt] = mrg(ls[Lrt], ls[Rrt], L1, R1 + tmp[2], L2, R2 + tmp[4], p);
rs[Lrt] = mrg(rs[Lrt], rs[Rrt], L1 + tmp[1], R1, L2 + tmp[3], R2, p);
pushup(Lrt);
return Lrt;
}
int qry(int x, int lx, int rx, int p) {
if (x == 0)
return 0;
if (lx + 1 == rx)
return val[x];
int m = (lx + rx) / 2;
pushdown(x);
if (p < m)
return qry(ls[x], lx, m, p);
return qry(rs[x], m, rx, p);
}
} st;
void dfs(int x) {
if (l[x] == 0) {//叶子
st.mdf(st.rt[x], 1, cur + 1, a[x], 1);
// printf("! leaf %d %d\n", x, st.qry(st.rt[x], 1, cur + 1, a[x]));
}
else if (r[x] == 0) {//一个儿子
dfs(l[x]);
st.rt[x] = st.rt[l[x]];
}
else { //两个儿子
dfs(l[x]);
dfs(r[x]);
st.rt[x] = st.mrg(st.rt[l[x]], st.rt[r[x]], 0, 0, 0, 0, p[x]);
// printf("! father %d %d\n", x, st.qry(st.rt[x], 1, cur + 1, 2));
}
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
int pr;
cin >> pr;
if (pr == 0)
continue;
if (l[pr] != 0)
r[pr] = i;
else
l[pr] = i;
}
inv10000 = fpow(10000, MOD - 2, MOD);
for (int i = 1; i <= n; i++) {
if (l[i] == 0) {
cin >> a[i];
mp[a[i]];
}
else {
cin >> p[i];
p[i] = 1ll * p[i] * inv10000 % MOD;
}
}
for (auto &i: mp) {
i.second = ++cur;
rev[cur] = i.first;
}
for (int i = 1; i <= n; i++) {
a[i] = mp[a[i]];
}
dfs(1);
long long ans = 0;
for (int i = 1; i <= cur; i++) {
ll prob = st.qry(st.rt[1], 1, cur + 1, i);
ans += 1ll * i * rev[i] % MOD * prob % MOD * prob % MOD;
ans %= MOD;
// cout << i << ':' << rev[i] << ' ' << prob << endl;
}
cout << ans << endl;
return 0;
}