Problem p02538 (C++) — buggy submission, verdict: Time Limit Exceeded

/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author Aman
 */

#include <bits/stdc++.h>
using namespace std;

using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
template <class T> using V = vector<T>;
template <class T> using VV = V<V<T>>;

#define pb push_back
#define fi first
#define se second
#define all(v) (v).begin(), (v).end()
#define rep(i, a, b) for (ll i = a; i <= b; i++)
#define repr(i, a, b) for (ll i = a; i >= b; i--)
#define pll pair<ll, ll>
#define tp tuple<ll, ll>

template <int D, typename T> struct vec : public vector<vec<D - 1, T>> {
  static_assert(D >= 1, "Vector dimension must be greater than zero!");

  template <typename... Args>
  vec(int n = 0, Args... args)
      : vector<vec<D - 1, T>>(n, vec<D - 1, T>(args...)) {}
};

template <typename T> struct vec<1, T> : public vector<T> {
  vec(int n = 0, T val = T()) : vector<T>(n, val) {}
};

template <typename T> inline bool chkmax(T &aa, T bb) {
  return aa < bb ? aa = bb, true : false;
}

template <typename T> inline bool chkmin(T &aa, T bb) {
  return aa > bb ? aa = bb, true : false;
}

template <typename T, typename S>
ostream &operator<<(ostream &os, const pair<T, S> &v) {
  os << "(";
  os << v.first << ", " << v.second << ")";
  return os;
}

template <typename T, typename S>
ostream &operator<<(ostream &os, const map<T, S> &v) {

  for (auto it : v)
    os << "[" << it.first << " : " << it.second << "]";

  return os;
}

template <typename T> ostream &operator<<(ostream &os, const set<T> &v) {
  os << "[";
  for (auto it : v) {
    os << it;
    if (it != *v.rbegin())
      os << ", ";
  }
  os << "]\\n";
  return os;
}

template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  os << "[";
  for (int i = 0; i < v.size(); ++i) {
    os << v[i];
    if (i != v.size() - 1)
      os << ", ";
  }
  os << "]\\n";
  return os;
}
template <typename T, T MOD = 1000000007> struct Mint {
  static constexpr T mod = MOD;
  T v;
  Mint() : v(0) {}
  Mint(signed v) : v(v) {}
  Mint(long long t) {
    v = t % MOD;
    if (v < 0)
      v += MOD;
  }

  Mint pow(long long k) {
    Mint res(1), tmp(v);
    while (k) {
      if (k & 1)
        res *= tmp;
      tmp *= tmp;
      k >>= 1;
    }
    return res;
  }

  static Mint add_identity() { return Mint(0); }
  static Mint mul_identity() { return Mint(1); }

  Mint inv() { return pow(MOD - 2); }

  Mint &operator+=(Mint a) {
    v += a.v;
    if (v >= MOD)
      v -= MOD;
    return *this;
  }
  Mint &operator-=(Mint a) {
    v += MOD - a.v;
    if (v >= MOD)
      v -= MOD;
    return *this;
  }
  Mint &operator*=(Mint a) {
    v = 1LL * v * a.v % MOD;
    return *this;
  }
  Mint &operator/=(Mint a) { return (*this) *= a.inv(); }

  Mint operator+(Mint a) const { return Mint(v) += a; }
  Mint operator-(Mint a) const { return Mint(v) -= a; }
  Mint operator*(Mint a) const { return Mint(v) *= a; }
  Mint operator/(Mint a) const { return Mint(v) /= a; }

  Mint operator-() const { return v ? Mint(MOD - v) : Mint(v); }

  bool operator==(const Mint a) const { return v == a.v; }
  bool operator!=(const Mint a) const { return v != a.v; }
  bool operator<(const Mint a) const { return v < a.v; }

  static Mint comb(long long n, int k) {
    Mint num(1), dom(1);
    for (int i = 0; i < k; i++) {
      num *= Mint(n - i);
      dom *= Mint(i + 1);
    }
    return num / dom;
  }
};
using M = Mint<ll, 998244353>;
ll N = 1e6;
M lol;
V<M> p10(N);
template <typename T, typename U> struct seg_tree_lazy {
  int S, H;

  T zero;
  vector<T> value;

  U noop;
  vector<bool> dirty;
  vector<U> prop;

  seg_tree_lazy<T, U>(int _S, T _zero = T(), U _noop = U()) {
    zero = _zero, noop = _noop;
    for (S = 1, H = 1; S < _S;)
      S *= 2, H++;

    value.resize(2 * S, zero);
    dirty.resize(2 * S, false);
    prop.resize(2 * S, noop);
  }

  void set_leaves(vector<T> &leaves) {
    copy(leaves.begin(), leaves.end(), value.begin() + S);
    fill(value.begin() + S + leaves.size(), value.end(), zero);

    for (int i = S - 1; i > 0; i--)
      value[i] = value[2 * i] + value[2 * i + 1];
  }

  void apply(int i, U &update) {
    value[i] = update(value[i]);
    if (i < S) {
      prop[i] = prop[i] + update;
      dirty[i] = true;
    }
  }

  void rebuild(int i) {
    for (int l = i / 2; l; l /= 2) {
      T combined = value[2 * l] + value[2 * l + 1];
      value[l] = prop[l](combined);
    }
  }

  void propagate(int i) {
    for (int h = H; h > 0; h--) {
      int l = i >> h;

      if (dirty[l]) {
        apply(2 * l, prop[l]);
        apply(2 * l + 1, prop[l]);

        prop[l] = noop;
        dirty[l] = false;
      }
    }
  }

  void upd(int i, int j, U update) {
    i += S, j += S;
    propagate(i), propagate(j);

    for (int l = i, r = j; l <= r; l /= 2, r /= 2) {
      if ((l & 1) == 1)
        apply(l++, update);
      if ((r & 1) == 0)
        apply(r--, update);
    }

    rebuild(i), rebuild(j);
  }

  T query(int i, int j) {
    i += S, j += S;
    propagate(i), propagate(j);

    T res_left = zero, res_right = zero;
    for (; i <= j; i /= 2, j /= 2) {
      if ((i & 1) == 1)
        res_left = res_left + value[i++];
      if ((j & 1) == 0)
        res_right = value[j--] + res_right;
    }
    return res_left + res_right;
  }
};

struct node {
  M x;
  ll sz;

  node operator+(const node &n) { return {x * p10[n.sz] + n.x, n.sz + sz}; }
};

struct update {
  ll id;
  node operator()(const node &n) {
    if (id != -1)
      return {(p10[n.sz] - 1) * M(id) * lol, n.sz};
    return n;
  }

  update operator+(const update &u) {
    if (u.id != -1)
      return u;
    return {id};
  }
};

class EReplaceDigits {
public:
  void solve(std::istream &cin, std::ostream &cout) {
    int n, q, x, y, z;
    cin >> n >> q;
    V<node> v(n, {1, 1});
    p10[0] = 1;
    rep(i, 1, N - 1) p10[i] = p10[i - 1] * 10;
    lol = M(1) / 9;

    seg_tree_lazy<node, update> seg(n, {0, 0}, {-1});
    seg.set_leaves(v);

    while (q--) {
      cin >> x >> y >> z;
      seg.upd(x - 1, y - 1, {z});
      string ans = to_string((ll)seg.query(0, n - 1).x.v);
      cout << ans << "\\n";
    }
  }
};

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  EReplaceDigits solver;
  std::istream &in(std::cin);
  std::ostream &out(std::cout);
  solver.solve(in, out);
  return 0;
}


Error: TLE

Fixed submission:

/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author Aman
 */

#include <bits/stdc++.h>
using namespace std;

using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
template <class T> using V = vector<T>;
template <class T> using VV = V<V<T>>;

#define pb push_back
#define fi first
#define se second
#define all(v) (v).begin(), (v).end()
#define rep(i, a, b) for (ll i = a; i <= b; i++)
#define repr(i, a, b) for (ll i = a; i >= b; i--)
#define pll pair<ll, ll>
#define tp tuple<ll, ll>

template <int D, typename T> struct vec : public vector<vec<D - 1, T>> {
  static_assert(D >= 1, "Vector dimension must be greater than zero!");

  template <typename... Args>
  vec(int n = 0, Args... args)
      : vector<vec<D - 1, T>>(n, vec<D - 1, T>(args...)) {}
};

template <typename T> struct vec<1, T> : public vector<T> {
  vec(int n = 0, T val = T()) : vector<T>(n, val) {}
};

template <typename T> inline bool chkmax(T &aa, T bb) {
  return aa < bb ? aa = bb, true : false;
}

template <typename T> inline bool chkmin(T &aa, T bb) {
  return aa > bb ? aa = bb, true : false;
}

template <typename T, typename S>
ostream &operator<<(ostream &os, const pair<T, S> &v) {
  os << "(";
  os << v.first << ", " << v.second << ")";
  return os;
}

template <typename T, typename S>
ostream &operator<<(ostream &os, const map<T, S> &v) {

  for (auto it : v)
    os << "[" << it.first << " : " << it.second << "]";

  return os;
}

template <typename T> ostream &operator<<(ostream &os, const set<T> &v) {
  os << "[";
  for (auto it : v) {
    os << it;
    if (it != *v.rbegin())
      os << ", ";
  }
  os << "]\\n";
  return os;
}

template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  os << "[";
  for (int i = 0; i < v.size(); ++i) {
    os << v[i];
    if (i != v.size() - 1)
      os << ", ";
  }
  os << "]\\n";
  return os;
}
template <typename T, T MOD = 1000000007> struct Mint {
  static constexpr T mod = MOD;
  T v;
  Mint() : v(0) {}
  Mint(signed v) : v(v) {}
  Mint(long long t) {
    v = t % MOD;
    if (v < 0)
      v += MOD;
  }

  Mint pow(long long k) {
    Mint res(1), tmp(v);
    while (k) {
      if (k & 1)
        res *= tmp;
      tmp *= tmp;
      k >>= 1;
    }
    return res;
  }

  static Mint add_identity() { return Mint(0); }
  static Mint mul_identity() { return Mint(1); }

  Mint inv() { return pow(MOD - 2); }

  Mint &operator+=(Mint a) {
    v += a.v;
    if (v >= MOD)
      v -= MOD;
    return *this;
  }
  Mint &operator-=(Mint a) {
    v += MOD - a.v;
    if (v >= MOD)
      v -= MOD;
    return *this;
  }
  Mint &operator*=(Mint a) {
    v = 1LL * v * a.v % MOD;
    return *this;
  }
  Mint &operator/=(Mint a) { return (*this) *= a.inv(); }

  Mint operator+(Mint a) const { return Mint(v) += a; }
  Mint operator-(Mint a) const { return Mint(v) -= a; }
  Mint operator*(Mint a) const { return Mint(v) *= a; }
  Mint operator/(Mint a) const { return Mint(v) /= a; }

  Mint operator-() const { return v ? Mint(MOD - v) : Mint(v); }

  bool operator==(const Mint a) const { return v == a.v; }
  bool operator!=(const Mint a) const { return v != a.v; }
  bool operator<(const Mint a) const { return v < a.v; }

  static Mint comb(long long n, int k) {
    Mint num(1), dom(1);
    for (int i = 0; i < k; i++) {
      num *= Mint(n - i);
      dom *= Mint(i + 1);
    }
    return num / dom;
  }
};
using M = Mint<ll, 998244353>;

template <typename T, typename U> struct seg_tree_lazy {
  int S, H;

  T zero;
  vector<T> value;

  U noop;
  vector<bool> dirty;
  vector<U> prop;

  seg_tree_lazy<T, U>(int _S, T _zero = T(), U _noop = U()) {
    zero = _zero, noop = _noop;
    for (S = 1, H = 1; S < _S;)
      S *= 2, H++;

    value.resize(2 * S, zero);
    dirty.resize(2 * S, false);
    prop.resize(2 * S, noop);
  }

  void set_leaves(vector<T> &leaves) {
    copy(leaves.begin(), leaves.end(), value.begin() + S);
    fill(value.begin() + S + leaves.size(), value.end(), zero);

    for (int i = S - 1; i > 0; i--)
      value[i] = value[2 * i] + value[2 * i + 1];
  }

  void apply(int i, U &update) {
    value[i] = update(value[i]);
    if (i < S) {
      prop[i] = prop[i] + update;
      dirty[i] = true;
    }
  }

  void rebuild(int i) {
    for (int l = i / 2; l; l /= 2) {
      T combined = value[2 * l] + value[2 * l + 1];
      value[l] = prop[l](combined);
    }
  }

  void propagate(int i) {
    for (int h = H; h > 0; h--) {
      int l = i >> h;

      if (dirty[l]) {
        apply(2 * l, prop[l]);
        apply(2 * l + 1, prop[l]);

        prop[l] = noop;
        dirty[l] = false;
      }
    }
  }

  void upd(int i, int j, U update) {
    i += S, j += S;
    propagate(i), propagate(j);

    for (int l = i, r = j; l <= r; l /= 2, r /= 2) {
      if ((l & 1) == 1)
        apply(l++, update);
      if ((r & 1) == 0)
        apply(r--, update);
    }

    rebuild(i), rebuild(j);
  }

  T query(int i, int j) {
    i += S, j += S;
    propagate(i), propagate(j);

    T res_left = zero, res_right = zero;
    for (; i <= j; i /= 2, j /= 2) {
      if ((i & 1) == 1)
        res_left = res_left + value[i++];
      if ((j & 1) == 0)
        res_right = value[j--] + res_right;
    }
    return res_left + res_right;
  }
};

struct node {
  M x;
  ll sz;

  node operator+(const node &n) {
    return {x * M(10).pow(n.sz) + n.x, n.sz + sz};
  }
};

struct update {
  ll id;
  node operator()(const node &n) {
    if (id != -1)
      return {(M(10).pow(n.sz) - 1) * M(id) / M(9), n.sz};
    return n;
  }

  update operator+(const update &u) {
    if (u.id != -1)
      return u;
    return {id};
  }
};

class EReplaceDigits {
public:
  void solve(std::istream &cin, std::ostream &cout) {
    int n, q, x, y, z;
    cin >> n >> q;
    V<node> v(n, {1, 1});

    seg_tree_lazy<node, update> seg(n, {0, 0}, {-1});
    seg.set_leaves(v);

    while (q--) {
      cin >> x >> y >> z;
      seg.upd(x - 1, y - 1, {z});
      string ans = to_string((ll)seg.query(0, n - 1).x.v);
      cout << ans << "\\n";
    }
  }
};

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  EReplaceDigits solver;
  std::istream &in(std::cin);
  std::ostream &out(std::cout);
  solver.solve(in, out);
  return 0;
}