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

#include <algorithm>
#include <array>
#include <bitset>
#include <boost/multiprecision/cpp_int.hpp>
#include <cstring>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdint.h>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;
using namespace boost::multiprecision;

using ll = long long;
using ull = unsigned long long;
using uint = unsigned int;
using ldb = long double;

#define REP(i, a, b) for (ll i = a; i < b; ++i)
#define PRI(s) cout << s << endl
#define PRIF(v, n) printf("%." #n "f\\n", v)
#define PRIY PRI("Yes")
#define PRIN PRI("No")
template <typename A, typename B> void mins(A &a, const B &b) {
  a = min(a, (A)b);
};
template <typename A, typename B> void maxs(A &a, const B &b) {
  a = max(a, (A)b);
};

template <typename T, typename M> class lazysegtree {
public:
  long long n;
  vector<T> dat;
  vector<M> lazy;
  T et;
  M em;
  function<T(T, T)> op; //(左の子、右の子）
  function<T(M, T)> map;
  function<M(M, M)> com; //(新しい,古い)

  lazysegtree(long long n_, T et, M em, function<T(T, T)> op,
              function<T(M, T)> map, function<M(M, M)> com)
      : et(et), em(em), op(op), map(map), com(com) {
    n = (1 << (int)ceil(log2(n_)));
    dat.resize(2 * n - 1, et);
    lazy.resize(2 * n - 1, em);
  }

  void prop(int ind) {
    dat[ind] = map(lazy[ind], dat[ind]);
    if (ind < n - 1) {
      lazy[2 * ind + 1] = com(lazy[ind], lazy[2 * ind + 1]);
      lazy[2 * ind + 2] = com(lazy[ind], lazy[2 * ind + 2]);
    }
    lazy[ind] = em;
  }

  T query(int a, int b, int l = 0, int r = -1, int ind = 0) {
    if (r == -1)
      r = n;
    if (r <= a || b <= l)
      return et;

    prop(ind);

    if (a <= l && r <= b)
      return dat[ind];
    else
      return op(query(a, b, l, (l + r) / 2, 2 * ind + 1),
                query(a, b, (l + r) / 2, r, 2 * ind + 2));
  }

  T apply(M m, int a, int b, int l = 0, int r = -1, int ind = 0) {
    if (r == -1)
      r = n;
    if (r <= a || b <= l) {
      prop(ind);
    } else if (a <= l && r <= b) {
      lazy[ind] = com(m, lazy[ind]);
      prop(ind);
    } else {
      prop(ind);
      dat[ind] = op(apply(m, a, b, l, (l + r) / 2, 2 * ind + 1),
                    apply(m, a, b, (l + r) / 2, r, 2 * ind + 2));
    }
    return dat[ind];
  }

  void build() {
    REP(i, 0, 2 * n - 1) prop(i);
    for (int i = n - 2; i >= 0; --i)
      dat[i] = op(dat[2 * i + 1], dat[2 * i + 2]);
  }
};

ll mod = 998244353;

// 拡張ユークリッドの互除法。戻り値は最大公約数、x,yはax+by=gcd(a,b)を満たす組の一つ
long long gcdext(long long a, long long b, long long &x, long long &y) {
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  }
  long long g = gcdext(b, a % b, y, x);
  y -= a / b * x;
  return g;
}

// モジュラ逆数
long long modinv(long long a, long long mod) {
  long long x, y;
  gcdext(a, mod, x, y);
  x = ((x % mod) + mod) % mod;
  return x;
}
ll modpow(ll r, ll n, ll mod) {
  ll ans = 1;
  ll tmp = r;
  while (n > 0) {
    if ((n & 1) > 0) {
      ans = ans * tmp % mod;
    }
    tmp = tmp * tmp % mod;
    n >>= 1;
  }
  return ans;
}

struct item {
  ll x, i, k;
};

ll em = -1;
item et = {0, -1, 0};

vector<ll> tbl10;
ll inv9;

ll com(ll a, ll b) {
  if (a == -1)
    return b;
  if (b == -1)
    return a;
  return a;
}
item mp(ll s, item a) {
  if (s == -1)
    return a;

  ll q = (tbl10[a.k] - 1);
  q = q * inv9 % mod;
  q = q * s % mod;

  return {q, a.i, a.k};
}
item op(item a, item b) {
  if (a.i < b.i)
    swap(a, b);
  if (b.i == -1)
    return a;
  return {(a.x * tbl10[a.i - b.i] % mod + b.x) % mod, b.i, a.k + b.k};
}

int main() {
  ll N, Q;
  cin >> N >> Q;
  lazysegtree<item, ll> tree{N, et, em, op, mp, com};
  inv9 = modinv(9, mod);
  tbl10.resize(N + 2);
  tbl10[0] = 1;
  REP(i, 1, N + 2) tbl10[i] = tbl10[i - 1] * 10 % mod;
  REP(i, 0, N) { tree.dat[tree.n - 1 + i] = item{1, N - 1 - i, 1}; }
  tree.build();
  REP(i, 0, Q) {
    ll l, r, d;
    cin >> l >> r >> d;
    tree.apply(d, l - 1, r);
    PRI(tree.query(0, N).x);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <array>
#include <bitset>
#include <boost/multiprecision/cpp_int.hpp>
#include <cstring>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdint.h>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;
using namespace boost::multiprecision;

using ll = long long;
using ull = unsigned long long;
using uint = unsigned int;
using ldb = long double;

#define REP(i, a, b) for (ll i = a; i < b; ++i)
#define PRI(s) cout << s << endl
#define PRIF(v, n) printf("%." #n "f\\n", v)
#define PRIY PRI("Yes")
#define PRIN PRI("No")
template <typename A, typename B> void mins(A &a, const B &b) {
  a = min(a, (A)b);
};
template <typename A, typename B> void maxs(A &a, const B &b) {
  a = max(a, (A)b);
};

template <typename T, typename M> class lazysegtree {
public:
  long long n;
  vector<T> dat;
  vector<M> lazy;
  T et;
  M em;
  function<T(T, T)> op; //(左の子、右の子）
  function<T(M, T)> map;
  function<M(M, M)> com; //(新しい,古い)

  lazysegtree(long long n_, T et, M em, function<T(T, T)> op,
              function<T(M, T)> map, function<M(M, M)> com)
      : et(et), em(em), op(op), map(map), com(com) {
    n = (1 << (int)ceil(log2(n_)));
    dat.resize(2 * n - 1, et);
    lazy.resize(2 * n - 1, em);
  }

  void prop(int ind) {
    dat[ind] = map(lazy[ind], dat[ind]);
    if (ind < n - 1) {
      lazy[2 * ind + 1] = com(lazy[ind], lazy[2 * ind + 1]);
      lazy[2 * ind + 2] = com(lazy[ind], lazy[2 * ind + 2]);
    }
    lazy[ind] = em;
  }

  T query(int a, int b, int l = 0, int r = -1, int ind = 0) {
    if (r == -1)
      r = n;
    if (r <= a || b <= l)
      return et;

    prop(ind);

    if (a <= l && r <= b)
      return dat[ind];
    else
      return op(query(a, b, l, (l + r) / 2, 2 * ind + 1),
                query(a, b, (l + r) / 2, r, 2 * ind + 2));
  }

  T apply(M m, int a, int b, int l = 0, int r = -1, int ind = 0) {
    if (r == -1)
      r = n;
    if (r <= a || b <= l) {
      prop(ind);
    } else if (a <= l && r <= b) {
      lazy[ind] = com(m, lazy[ind]);
      prop(ind);
    } else {
      prop(ind);
      dat[ind] = op(apply(m, a, b, l, (l + r) / 2, 2 * ind + 1),
                    apply(m, a, b, (l + r) / 2, r, 2 * ind + 2));
    }
    return dat[ind];
  }

  void build() {
    REP(i, 0, 2 * n - 1) prop(i);
    for (int i = n - 2; i >= 0; --i)
      dat[i] = op(dat[2 * i + 1], dat[2 * i + 2]);
  }
};

ll mod = 998244353;

// 拡張ユークリッドの互除法。戻り値は最大公約数、x,yはax+by=gcd(a,b)を満たす組の一つ
long long gcdext(long long a, long long b, long long &x, long long &y) {
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  }
  long long g = gcdext(b, a % b, y, x);
  y -= a / b * x;
  return g;
}

// モジュラ逆数
long long modinv(long long a, long long mod) {
  long long x, y;
  gcdext(a, mod, x, y);
  x = ((x % mod) + mod) % mod;
  return x;
}
ll modpow(ll r, ll n, ll mod) {
  ll ans = 1;
  ll tmp = r;
  while (n > 0) {
    if ((n & 1) > 0) {
      ans = ans * tmp % mod;
    }
    tmp = tmp * tmp % mod;
    n >>= 1;
  }
  return ans;
}

struct item {
  ll x, i, k;
};

ll com(ll a, ll b) {
  if (a == -1)
    return b;
  if (b == -1)
    return a;
  return a;
}
item mp(ll s, item a) {
  if (s == -1)
    return a;
  return {(modpow(10, a.k, mod) - 1) * modinv(9, mod) % mod * s % mod, a.i,
          a.k};
}
item op(item a, item b) {
  if (a.i < b.i)
    swap(a, b);
  if (b.i == -1)
    return a;
  return {(a.x * modpow(10, a.i - b.i, mod) % mod + b.x) % mod, b.i, a.k + b.k};
}

ll em = -1;
item et = {0, -1, 0};

int main() {
  ll N, Q;
  cin >> N >> Q;
  lazysegtree<item, ll> tree{N, et, em, op, mp, com};
  REP(i, 0, N) { tree.dat[tree.n - 1 + i] = item{1, N - 1 - i, 1}; }
  tree.build();
  REP(i, 0, Q) {
    ll l, r, d;
    cin >> l >> r >> d;
    tree.apply(d, l - 1, r);
    PRI(tree.query(0, N).x);
  }
  return 0;
}