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

// #pragma warning(disable:4996)
// #include <Windows.h>
#include <algorithm>
#include <bitset>
#include <cassert>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <vector>
// #include <boost/multiprecision/cpp_int.hpp>
#include <bitset>
#include <complex>
#include <cstdio>
#include <list>
// #include <stdio.h>

//< in.txt > out.txt
using namespace std;
// std::ios::sync_with_stdio(false);
// std::cin.tie(0);
const long long MOD = 1e9 + 7;
const long long INF = 1e18;
typedef long long LL;
typedef long double LD;
// typedef boost::multiprecision::cpp_int bigint;
typedef pair<LL, LL> PLL;
typedef pair<int, int> PI;
typedef pair<LD, LL> pdl;
typedef pair<LD, LD> pdd;
typedef vector<LL> VLL;
typedef vector<VLL> VVLL;
typedef vector<int> VI;
typedef vector<vector<int>> VVI;
typedef unsigned long long ULL;
template <class T>
using pqueue = priority_queue<T, vector<T>, function<bool(T, T)>>;

template <class T> inline void chmin(T &a, T b) { a = min(a, b); }

template <class T> inline void chmax(T &a, T b) { a = max(a, b); }

void input();
void solve();

void daminput();
void naive();

void outputinput();

int main() {
  std::cin.tie(0);
  std::ios::sync_with_stdio(false);
  input();
  // daminput();
  solve();
  // naive();
  // outputinput();
  return 0;
}

//////////////////////////////////////////////////
//////////////////////////////////////////////////

int N, Q;
VLL L, R, D;
LL mod = 998244353;

void input() {
  cin >> N >> Q;
  L.resize(Q);
  R.resize(Q);
  D.resize(Q);
  for (int q = 0; q < Q; q++)
    cin >> L[q] >> R[q] >> D[q];
}

void daminput() {}

// TT(T,T):=モノイドの乗算
// MT(M,T,LL):=モノイドに対する左作用(第3項は要素数)
// MM(M,M):=左作用の合成
template <class T, class M> class LazySegtree {
public:
  vector<T> seg;
  vector<M> lazy; // 実、更新の必要性
  typedef function<T(T, T)> TT;
  typedef function<T(M, T, int)> MT;
  typedef function<M(M, M)> MM;
  TT tt;
  MT mt;
  MM mm;
  M Me;
  T Te;
  int snum; // 何回シフトで下段から1に行けるか
  LazySegtree(int N, TT _tt, MT _mtn, MM _mm, T te, M me) {
    int RN = 1;
    snum = 0;
    while (RN < N) {
      RN *= 2;
      snum++;
    }
    Te = te;
    Me = me;
    seg.resize(2 * RN, Te);
    lazy.resize(2 * RN, Me);
    tt = _tt;
    mt = _mtn;
    mm = _mm;
  }
  LazySegtree(vector<T> &vec, TT _tt, MT _mt, MM _mm, T te, M me) {
    int RN = 1;
    snum = 0;
    while (RN < vec.size()) {
      RN *= 2;
      snum++;
    }
    Te = te;
    Me = me;
    seg.resize(2 * RN, Te);
    lazy.resize(2 * RN, Me);
    tt = _tt;
    mt = _mt;
    mm = _mm;
    for (int n = 0; n < vec.size(); n++)
      seg[RN + n] = vec[n];
    for (int n = RN - 1; n >= 1; n--) {
      seg[n] = tt(seg[2 * n], seg[2 * n + 1]);
    }
  }
  void eval(int k, int l, int r) {
    if (k >= seg.size())
      return;
    if (lazy[k] == Me)
      return;
    seg[k] = mt(lazy[k], seg[k], r - l + 1);
    if (k < seg.size() / 2) {
      lazy[2 * k] = mm(lazy[k], lazy[2 * k]);
      lazy[2 * k + 1] = mm(lazy[k], lazy[2 * k + 1]);
    }
    lazy[k] = Me;
  }
  void apply(int a, int b, M m, int k, int l, int r) {
    eval(k, l, r);
    if (r < a || b < l)
      return;
    if (a <= l && r <= b) {
      lazy[k] = mm(m, lazy[k]);
      eval(k, l, r);
    } else {
      apply(a, b, m, 2 * k, l, (l + r) / 2);
      apply(a, b, m, 2 * k + 1, (l + r) / 2 + 1, r);
      seg[k] = tt(seg[2 * k], seg[2 * k + 1]);
    }
  }
  void apply(int a, int b, M m) { apply(a, b, m, 1, 0, seg.size() / 2 - 1); }
  T get(int a, int b, int k, int l, int r) {
    if (r < a || b < l)
      return Te;
    eval(k, l, r);
    if (a <= l && r <= b)
      return seg[k];
    else
      return tt(get(a, b, 2 * k, l, (l + r) / 2),
                get(a, b, 2 * k + 1, (l + r) / 2 + 1, r));
  }
  T get(int a, int b) { return get(a, b, 1, 0, seg.size() / 2 - 1); }
  void set(int n, T t) {
    int RN = seg.size() / 2;
    int l = 0, r = RN - 1;
    for (int t = snum; t > 0; t--) {
      eval((n + RN) >> t, l, r);
      if (((n + RN) >> (t - 1)) & 1) {
        l = ((l + r) >> 1) + 1;
      } else {
        r = (l + r) >> 1;
      }
    }
    eval((n + RN), n, n);
    seg[n + RN] = t;
    l = n;
    r = n;
    n += RN;
    while ((n >> 1) > 0) {
      if (n & 1) {
        l = 2 * l - r - 1;
      } else {
        r = 2 * r - l + 1;
      }
      n >>= 1;
      eval(n * 2, l, (l + r) >> 1);
      eval(n * 2 + 1, ((l + r) >> 1) + 1, r);
      seg[n] = tt(seg[2 * n], seg[2 * n + 1]);
    }
  }
};

LL modpow(LL base, int p) {
  if (p == 0)
    return 1;
  LL ans = modpow(base, p >> 1);
  ans = (ans * ans) % mod;
  if (p & 1) {
    ans = (ans * base) % mod;
  }
  return ans;
}

void solve() {
  LL ninerev = modpow(9, mod - 2);
  vector<PLL> initial(N, PLL(1, 1));
  VLL tle(2e5 + 1, 1); // 10^n
  for (int n = 1; n <= 2e5; n++) {
    tle[n] = (tle[n - 1] * 10) % mod;
  }
  LazySegtree<PLL, LL> seg(
      initial,
      [&](PLL a, PLL b) {
        if (a.second == 0)
          return b;
        if (b.second == 0)
          return a;
        LL first = (a.first * tle[b.second] + b.first) % mod;
        LL second = a.second + b.second;
        return PLL(first, second);
      },
      [&](LL m, PLL t, int n) {
        if (t.second == 0)
          return t;
        if (m == -1)
          return t;
        LL res = (tle[n] - 1) % mod;
        if (res < 0)
          res += mod;
        res = (res * ninerev) % mod;
        res = (res * m) % mod;
        return PLL(res, n);
      },
      [&](LL m2, LL m1) {
        if (m2 == -1)
          return m1;
        return m2;
      },
      PLL(1, 0), (LL)(-1));
  for (int q = 0; q < Q; q++) {
    seg.apply(L[q] - 1, R[q] - 1, D[q]);
    cout << seg.get(0, N - 1).first << "\\n";
  }
}

void naive() {}

void outputinput() {}

Error: TLE

Fixed submission:

// #pragma warning(disable:4996)
// #include <Windows.h>
#include <algorithm>
#include <bitset>
#include <cassert>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <vector>
// #include <boost/multiprecision/cpp_int.hpp>
#include <bitset>
#include <complex>
#include <cstdio>
#include <list>
// #include <stdio.h>

//< in.txt > out.txt
using namespace std;
// std::ios::sync_with_stdio(false);
// std::cin.tie(0);
const long long MOD = 1e9 + 7;
const long long INF = 1e18;
typedef long long LL;
typedef long double LD;
// typedef boost::multiprecision::cpp_int bigint;
typedef pair<LL, LL> PLL;
typedef pair<int, int> PI;
typedef pair<LD, LL> pdl;
typedef pair<LD, LD> pdd;
typedef vector<LL> VLL;
typedef vector<VLL> VVLL;
typedef vector<int> VI;
typedef vector<vector<int>> VVI;
typedef unsigned long long ULL;
template <class T>
using pqueue = priority_queue<T, vector<T>, function<bool(T, T)>>;

template <class T> inline void chmin(T &a, T b) { a = min(a, b); }

template <class T> inline void chmax(T &a, T b) { a = max(a, b); }

void input();
void solve();

void daminput();
void naive();

void outputinput();

int main() {
  std::cin.tie(0);
  std::ios::sync_with_stdio(false);
  input();
  // daminput();
  solve();
  // naive();
  // outputinput();
  return 0;
}

//////////////////////////////////////////////////
//////////////////////////////////////////////////

int N, Q;
VLL L, R, D;
LL mod = 998244353;

void input() {
  cin >> N >> Q;
  L.resize(Q);
  R.resize(Q);
  D.resize(Q);
  for (int q = 0; q < Q; q++)
    cin >> L[q] >> R[q] >> D[q];
}

void daminput() {}

// TT(T,T):=モノイドの乗算
// MT(M,T,LL):=モノイドに対する左作用(第3項は要素数)
// MM(M,M):=左作用の合成
template <class T, class M> class LazySegtree {
public:
  vector<T> seg;
  vector<M> lazy; // 実、更新の必要性
  typedef function<T(T, T)> TT;
  typedef function<T(M, T, int)> MT;
  typedef function<M(M, M)> MM;
  TT tt;
  MT mt;
  MM mm;
  M Me;
  T Te;
  int snum; // 何回シフトで下段から1に行けるか
  LazySegtree(int N, TT _tt, MT _mtn, MM _mm, T te, M me) {
    int RN = 1;
    snum = 0;
    while (RN < N) {
      RN *= 2;
      snum++;
    }
    Te = te;
    Me = me;
    seg.resize(2 * RN, Te);
    lazy.resize(2 * RN, Me);
    tt = _tt;
    mt = _mtn;
    mm = _mm;
  }
  LazySegtree(vector<T> &vec, TT _tt, MT _mt, MM _mm, T te, M me) {
    int RN = 1;
    snum = 0;
    while (RN < vec.size()) {
      RN *= 2;
      snum++;
    }
    Te = te;
    Me = me;
    seg.resize(2 * RN, Te);
    lazy.resize(2 * RN, Me);
    tt = _tt;
    mt = _mt;
    mm = _mm;
    for (int n = 0; n < vec.size(); n++)
      seg[RN + n] = vec[n];
    for (int n = RN - 1; n >= 1; n--) {
      seg[n] = tt(seg[2 * n], seg[2 * n + 1]);
    }
  }
  void eval(int k, int l, int r) {
    if (k >= seg.size())
      return;
    if (lazy[k] == Me)
      return;
    seg[k] = mt(lazy[k], seg[k], r - l + 1);
    if (k < seg.size() / 2) {
      lazy[2 * k] = mm(lazy[k], lazy[2 * k]);
      lazy[2 * k + 1] = mm(lazy[k], lazy[2 * k + 1]);
    }
    lazy[k] = Me;
  }
  void apply(int a, int b, M m, int k, int l, int r) {
    eval(k, l, r);
    if (r < a || b < l)
      return;
    if (a <= l && r <= b) {
      lazy[k] = mm(m, lazy[k]);
      eval(k, l, r);
    } else {
      apply(a, b, m, 2 * k, l, (l + r) / 2);
      apply(a, b, m, 2 * k + 1, (l + r) / 2 + 1, r);
      seg[k] = tt(seg[2 * k], seg[2 * k + 1]);
    }
  }
  void apply(int a, int b, M m) { apply(a, b, m, 1, 0, seg.size() / 2 - 1); }
  T get(int a, int b, int k, int l, int r) {
    if (r < a || b < l)
      return Te;
    eval(k, l, r);
    if (a <= l && r <= b)
      return seg[k];
    else
      return tt(get(a, b, 2 * k, l, (l + r) / 2),
                get(a, b, 2 * k + 1, (l + r) / 2 + 1, r));
  }
  T get(int a, int b) { return get(a, b, 1, 0, seg.size() / 2 - 1); }
  void set(int n, T t) {
    int RN = seg.size() / 2;
    int l = 0, r = RN - 1;
    for (int t = snum; t > 0; t--) {
      eval((n + RN) >> t, l, r);
      if (((n + RN) >> (t - 1)) & 1) {
        l = ((l + r) >> 1) + 1;
      } else {
        r = (l + r) >> 1;
      }
    }
    eval((n + RN), n, n);
    seg[n + RN] = t;
    l = n;
    r = n;
    n += RN;
    while ((n >> 1) > 0) {
      if (n & 1) {
        l = 2 * l - r - 1;
      } else {
        r = 2 * r - l + 1;
      }
      n >>= 1;
      eval(n * 2, l, (l + r) >> 1);
      eval(n * 2 + 1, ((l + r) >> 1) + 1, r);
      seg[n] = tt(seg[2 * n], seg[2 * n + 1]);
    }
  }
};

LL modpow(LL base, int p) {
  if (p == 0)
    return 1;
  LL ans = modpow(base, p >> 1);
  ans = (ans * ans) % mod;
  if (p & 1) {
    ans = (ans * base) % mod;
  }
  return ans;
}

void solve() {
  LL ninerev = modpow(9, mod - 2);
  vector<PLL> initial(N, PLL(1, 1));
  LazySegtree<PLL, LL> seg(
      initial,
      [&](PLL a, PLL b) {
        if (a.second == 0)
          return b;
        if (b.second == 0)
          return a;
        LL first = (a.first * modpow(10, b.second) + b.first) % mod;
        LL second = a.second + b.second;
        return PLL(first, second);
      },
      [&](LL m, PLL t, int n) {
        if (t.second == 0)
          return t;
        if (m == -1)
          return t;
        LL res = (modpow(10, n) - 1) % mod;
        if (res < 0)
          res += mod;
        res = (res * ninerev) % mod;
        res = (res * m) % mod;
        return PLL(res, n);
      },
      [&](LL m2, LL m1) {
        if (m2 == -1)
          return m1;
        return m2;
      },
      PLL(1, 0), (LL)(-1));
  for (int q = 0; q < Q; q++) {
    seg.apply(L[q] - 1, R[q] - 1, D[q]);
    cout << seg.get(0, N - 1).first << "\\n";
  }
}

void naive() {}

void outputinput() {}