func_code_string: #include <bits/stdc++.h>   using namespace std;   const int INF = 2147483647;   const long long LLINF = 9223372036854775807LL;   template <int MOD>   struct Num {     int x;     Num() : x(0) {}     explicit Num(int x, bool skip_check = false) {       if (skip_check)         this->x = x;       else {         if (x >= 0 && x < MOD)           this->x = x;         else {           this->x = x % MOD;           if (this->x < 0) this->x += MOD;         };       }     }     Num<MOD> operator+(const Num<MOD>& oth) const {       int rem = this->x + oth.x;       if (rem >= MOD) rem -= MOD;       return Num(rem, true);     }     Num<MOD> operator-(const Num<MOD>& oth) const {       int rem = this->x - oth.x;       if (rem < 0) rem += MOD;       return Num(rem, true);     }     Num<MOD> operator*(const Num<MOD>& oth) const {       int rem = (long long)this->x * oth.x % MOD;       return Num(rem, true);     }     Num<MOD> to_pow(int n) const {       Num<MOD> res(1);       Num<MOD> cur = *this;       while (n) {         if (n & 1) res = res * cur;         cur = cur * cur;         n >>= 1;       }       return res;     }     Num<MOD> inv_prime() const { return this->to_pow(MOD - 2); }     Num<MOD> operator/(const Num<MOD>& oth) const {       return *this * oth.inv_prime();     }     bool operator==(const Num<MOD>& oth) const { return x == oth.x; }     bool operator!=(const Num<MOD>& oth) const { return !(x == oth); }   };   int sgn(long long x) {     if (x > 0) return 1;     if (x < 0) return -1;     return 0;   }   struct Frac {     int numer, den;     explicit Frac(int numer, int den) : numer(numer), den(den) {}     int cmp(const Frac& oth) const {       long long res_numer =           (long long)numer * oth.den - (long long)oth.numer * den;       long long res_den = (long long)den * oth.den;       return sgn(res_numer) * sgn(res_den);     }   };   const int mod = 998244353;   struct Event {     int lind;     int ldir, rdir;     Frac t;     Event(int lind, int ldir, int rdir, Frac t)         : lind(lind), ldir(ldir), rdir(rdir), t(t) {}     bool operator<(const Event& oth) const { return this->t.cmp(oth.t) < 0; }   };   struct Pipe {     int x, v, p_right;     Pipe() {}     Pipe(int x, int v, int p_right) : x(x), v(v), p_right(p_right) {}   };   struct TreeNodeData {     Num<mod> p_ok[2][2];     Num<mod> p_all[2][2];     TreeNodeData() {}     TreeNodeData combine(const TreeNodeData& oth, const int forb[2][2]) const {       TreeNodeData res;       for (int d1 = 0; d1 < 2; ++d1)         for (int d2 = 0; d2 < 2; ++d2)           for (int d3 = 0; d3 < 2; ++d3)             for (int d4 = 0; d4 < 2; ++d4) {               res.p_all[d1][d4] =                   res.p_all[d1][d4] + p_all[d1][d2] * oth.p_all[d3][d4];               if (forb[d2][d3]) continue;               res.p_ok[d1][d4] =                   res.p_ok[d1][d4] + p_ok[d1][d2] * oth.p_ok[d3][d4];             }       return res;     }   };   const int maxtr = 270000;   TreeNodeData tree[maxtr];   const int maxn = 100010;   int forb[maxn][2][2];   vector<TreeNodeData> leaves;   void build_tree(int v, int L, int R) {     if (L == R) {       tree[v] = leaves[L];       return;     }     int m = (L + R) >> 1;     build_tree(v + v + 1, L, m);     build_tree(v + v + 2, m + 1, R);     tree[v] = tree[v + v + 1].combine(tree[v + v + 2], forb[m]);   }   void tree_update(int v, int L, int R, int pos) {     if (L == R) return;     int m = (L + R) >> 1;     if (pos <= m)       tree_update(v + v + 1, L, m, pos);     else       tree_update(v + v + 2, m + 1, R, pos);     tree[v] = tree[v + v + 1].combine(tree[v + v + 2], forb[m]);   }   int main() {     int n;     scanf( %d , &n);     vector<Pipe> pipes;     for (int i = 0; i < n; ++i) {       int cx, cv, cp;       scanf( %d%d%d , &cx, &cv, &cp);       pipes.push_back(Pipe(cx, cv, cp));     }     for (auto pipe : pipes) {       TreeNodeData curres;       curres.p_ok[1][1] = curres.p_all[1][1] =           Num<mod>(pipe.p_right) / Num<mod>(100);       curres.p_ok[0][0] = curres.p_all[0][0] =           Num<mod>(100 - pipe.p_right) / Num<mod>(100);       leaves.push_back(curres);     }     build_tree(0, 0, n - 1);     vector<Event> events;     for (int i = 0; i + 1 < n; ++i) {       auto p1 = pipes[i];       auto p2 = pipes[i + 1];       events.push_back(Event(i, 1, 0, Frac(p2.x - p1.x, p1.v + p2.v)));       if (p1.v > p2.v)         events.push_back(Event(i, 1, 1, Frac(p2.x - p1.x, p1.v - p2.v)));       else if (p2.v > p1.v)         events.push_back(Event(i, 0, 0, Frac(p2.x - p1.x, p2.v - p1.v)));     }     sort(events.begin(), events.end());     Num<mod> result(0);     Num<mod> pred_nok_prob(0);     for (int ev_ind = 0; ev_ind < int((events).size());) {       int fr_ev = ev_ind;       int to_ev = ev_ind;       while (to_ev < int((events).size()) &&              events[fr_ev].t.cmp(events[to_ev].t) == 0)         ++to_ev;       Num<mod> cur_ok_prob(tree[0].p_ok[0][0] + tree[0].p_ok[0][1] +                            tree[0].p_ok[1][0] + tree[0].p_ok[1][1]);       for (int i = fr_ev; i < to_ev; ++i) {         forb[events[i].lind][events[i].ldir][events[i].rdir] = 1;         tree_update(0, 0, n - 1, events[i].lind);       }       Num<mod> cur_nok_prob = ((tree[0].p_all[0][0] + tree[0].p_all[0][1] +                                 tree[0].p_all[1][0] + tree[0].p_all[1][1]) -                                (tree[0].p_ok[0][0] + tree[0].p_ok[0][1] +                                 tree[0].p_ok[1][0] + tree[0].p_ok[1][1]));       Num<mod> cur_delta = (cur_nok_prob - pred_nok_prob) *                            Num<mod>(events[fr_ev].t.numer) /                            Num<mod>(events[fr_ev].t.den);       result = result + cur_delta;       pred_nok_prob = cur_nok_prob;       ev_ind = to_ev;     }     cout << result.x << endl;     return 0;   }   