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

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
#include <ext/pb_ds/tree_policy.hpp>

const double pi = 3.141592653589793238462643383279;
using namespace std;
using namespace __gnu_pbds;
// typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<long long, long long> PLL;
typedef pair<int, PII> TIII;
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<LL> VLL;
typedef vector<VLL> VVLL;

// container util
//------------------------------------------
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SQ(a) ((a) * (a))
#define EACH(i, c)                                                             \\
  for (typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort((c).begin(), (c).end())

// repetition
//------------------------------------------
#define FOR(i, s, n) for (int i = s; i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define MOD 1000000007

#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define trav(a, x) for (auto &a : x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()

typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)

const ll INF = -(1LL << 60);

const long double EPS = 1e-6, PI = acos((long double)-1);

// ここから編集

const int MOD2 = 998244353;
ll modPow(ll x, ll n, ll mod = MOD) {
  if (n < 0)
    return 0;
  ll res = 1;
  while (n) {
    if (n & 1)
      res = (res * x) % mod;

    res %= mod;
    x = x * x % mod;
    n >>= 1;
  }
  return res;
}

long long extGCD(long long a, long long b, long long &x, long long &y) {
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  }
  long long d = extGCD(b, a % b, y, x);
  y -= a / b * x;
  return d;
}
// 負の数にも対応した mod (a = -11 とかでも OK)
inline long long mod(long long a, long long m) { return (a % m + m) % m; }

// 逆元計算 (ここでは a と m が互いに素であることが必要)
long long modinv(long long a, long long m) {
  long long x, y;
  extGCD(a, m, x, y);
  return mod(x, m); // 気持ち的には x % m だが、x が負かもしれないので
}

ll inv9;
ll pows[201010];
ll N, Q;
template <typename T> struct LazySegmentTree {
  const int INF = numeric_limits<int>::max();
  int n0;
  vector<T> node, lazy;

  LazySegmentTree(vector<T> &v) {
    int n = v.size();
    n0 = 1;
    while (n0 < n)
      n0 <<= 1;
    node.resize(2 * n0 - 1);
    lazy.assign(2 * n0 - 1, INF);
    for (int i = 0; i < n; i++)
      node[i + n0 - 1] = v[i] * pows[N - i - 1] % MOD2;
    for (int i = n0 - 2; i >= 0; i--)
      node[i] = node[i * 2 + 1] + node[i * 2 + 2];
  }

  void eval(int k, int l, int r) {
    if (lazy[k] == INF)
      return;

    if (k < n0 - 1) {
      lazy[k * 2 + 1] = lazy[k];
      lazy[k * 2 + 2] = lazy[k];
    }
    // cout << l << " " << r << endl;
    ll r1 = (pows[N - r] - 1 + MOD2) % MOD2 * inv9 % MOD2;
    ll l1 = (pows[N - l] - 1 + MOD2) % MOD2 * inv9 % MOD2;
    // cout << l1-r1 << endl;
    node[k] = lazy[k] * (l1 - r1 + MOD2) % MOD2;
    lazy[k] = INF;
  }

  void update(int a, int b, T x, int k, ll l, ll r) {
    eval(k, l, r);
    if (a <= l && r <= b) {
      lazy[k] = x;
      eval(k, l, r);
    } else if (a < r && l < b) {
      update(a, b, x, k * 2 + 1, l, (l + r) / 2);
      update(a, b, x, k * 2 + 2, (l + r) / 2, r);
      node[k] = (node[k * 2 + 1] + node[k * 2 + 2]) % MOD2;
    }
  }

  void update(int l, int r, T x) { update(l, r, x, 0, 0, n0); }

  T query(int a, int b, int k, ll l, ll r) {
    eval(k, l, r);
    if (r <= a || b <= l)
      return 0;
    else if (a <= l && r <= b) {
      return node[k];
    } else {
      T vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
      T vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
      return (vl + vr) % MOD2;
    }
  }
  T query(int l, int r) { return query(l, r, 0, 0, n0); }

  inline T operator[](int a) { return query(a, a + 1); }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(7);

  cin >> N >> Q;
  inv9 = modinv(9, MOD2);
  pows[0] = 1;
  for (int i = 0; i <= N + 1; i++) {
    pows[i + 1] = (pows[i] * 10) % MOD2;
  }
  vector<ll> v(N, 1);
  LazySegmentTree<ll> seg(v);
  // cout << seg.query(0, N) << endl;
  REP(i, Q) {
    int l, r, d;
    cin >> l >> r >> d;
    l--;
    r--;
    seg.update(l, r + 1, d);
    cout << seg.query(0, N) << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
#include <ext/pb_ds/tree_policy.hpp>

const double pi = 3.141592653589793238462643383279;
using namespace std;
using namespace __gnu_pbds;
// typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<long long, long long> PLL;
typedef pair<int, PII> TIII;
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<LL> VLL;
typedef vector<VLL> VVLL;

// container util
//------------------------------------------
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SQ(a) ((a) * (a))
#define EACH(i, c)                                                             \\
  for (typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort((c).begin(), (c).end())

// repetition
//------------------------------------------
#define FOR(i, s, n) for (int i = s; i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define MOD 1000000007

#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define trav(a, x) for (auto &a : x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()

typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)

const ll INF = -(1LL << 60);

const long double EPS = 1e-6, PI = acos((long double)-1);

// ここから編集

const int MOD2 = 998244353;
ll modPow(ll x, ll n, ll mod = MOD) {
  if (n < 0)
    return 0;
  ll res = 1;
  while (n) {
    if (n & 1)
      res = (res * x) % mod;

    res %= mod;
    x = x * x % mod;
    n >>= 1;
  }
  return res;
}

long long extGCD(long long a, long long b, long long &x, long long &y) {
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  }
  long long d = extGCD(b, a % b, y, x);
  y -= a / b * x;
  return d;
}
// 負の数にも対応した mod (a = -11 とかでも OK)
inline long long mod(long long a, long long m) { return (a % m + m) % m; }

// 逆元計算 (ここでは a と m が互いに素であることが必要)
long long modinv(long long a, long long m) {
  long long x, y;
  extGCD(a, m, x, y);
  return mod(x, m); // 気持ち的には x % m だが、x が負かもしれないので
}

ll N, Q;
template <typename T> struct LazySegmentTree {
  const int INF = numeric_limits<int>::max();
  int n0;
  vector<T> node, lazy;

  LazySegmentTree(vector<T> &v) {
    int n = v.size();
    n0 = 1;
    while (n0 < n)
      n0 <<= 1;
    node.resize(2 * n0 - 1);
    lazy.assign(2 * n0 - 1, INF);
    for (int i = 0; i < n; i++)
      node[i + n0 - 1] = v[i] * modPow(10, N - i - 1, MOD2) % MOD2;
    for (int i = n0 - 2; i >= 0; i--)
      node[i] = node[i * 2 + 1] + node[i * 2 + 2];
  }

  void eval(int k, int l, int r) {
    if (lazy[k] == INF)
      return;

    if (k < n0 - 1) {
      lazy[k * 2 + 1] = lazy[k];
      lazy[k * 2 + 2] = lazy[k];
    }
    // cout << l << " " << r << endl;
    ll r1 =
        (modPow(10, N - r, MOD2) - 1 + MOD2) % MOD2 * modinv(9, MOD2) % MOD2;
    ll l1 =
        (modPow(10, N - l, MOD2) - 1 + MOD2) % MOD2 * modinv(9, MOD2) % MOD2;
    // cout << l1-r1 << endl;
    node[k] = lazy[k] * (l1 - r1 + MOD2) % MOD2;
    lazy[k] = INF;
  }

  void update(int a, int b, T x, int k, ll l, ll r) {
    eval(k, l, r);
    if (a <= l && r <= b) {
      lazy[k] = x;
      eval(k, l, r);
    } else if (a < r && l < b) {
      update(a, b, x, k * 2 + 1, l, (l + r) / 2);
      update(a, b, x, k * 2 + 2, (l + r) / 2, r);
      node[k] = (node[k * 2 + 1] + node[k * 2 + 2]) % MOD2;
    }
  }

  void update(int l, int r, T x) { update(l, r, x, 0, 0, n0); }

  T query(int a, int b, int k, ll l, ll r) {
    eval(k, l, r);
    if (r <= a || b <= l)
      return 0;
    else if (a <= l && r <= b) {
      return node[k];
    } else {
      T vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
      T vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
      return (vl + vr) % MOD2;
    }
  }
  T query(int l, int r) { return query(l, r, 0, 0, n0); }

  inline T operator[](int a) { return query(a, a + 1); }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(7);

  cin >> N >> Q;
  vector<ll> v(N, 1);
  LazySegmentTree<ll> seg(v);
  // cout << seg.query(0, N) << endl;
  REP(i, Q) {
    int l, r, d;
    cin >> l >> r >> d;
    l--;
    r--;
    seg.update(l, r + 1, d);
    cout << seg.query(0, N) << endl;
  }
  return 0;
}