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

#include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <chrono>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

using namespace std;
struct _ {
  ios_base::Init i;
  _() { ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL); }
} _;

const int maxn = 2e5;
const int MOD = 998244353;

class Modint {
public:
  long long val;

  Modint(long long _val = 0) : val((_val + MOD) % MOD) {}

  Modint operator+(Modint other) { return Modint(val + other.val); }

  void operator+=(Modint other) {
    val += other.val;
    val %= MOD;
  }

  Modint operator-() { return Modint(MOD - val); }

  Modint operator-(Modint other) { return Modint(val + MOD - other.val); }

  void operator-=(Modint other) {
    val += MOD - other.val;
    val %= MOD;
  }

  Modint operator*(Modint other) { return Modint(val * other.val); }

  void operator*=(Modint other) {
    val *= other.val;
    val %= MOD;
  }

  bool operator==(Modint other) { return val == other.val; }

  bool operator!=(Modint other) { return val != other.val; }
};

Modint exp(Modint a, int k) {
  if (k == 0) {
    return Modint(1);
  } else if (k % 2 == 0) {
    Modint half = exp(a, k / 2);
    return half * half;
  } else {
    return a * exp(a, k - 1);
  }
}

Modint inv(Modint a) { return exp(a, MOD - 2); }

ostream &operator<<(ostream &out, Modint p) {
  out << p.val;
  return out;
}

// vector<int> a(maxn, 0);
int n, q;
Modint INV9 = inv(9);
vector<Modint> pw(maxn + 1, 1);
vector<Modint> tree(4 * maxn + 1, 0); // update->[l,r]+=inc, query->sum([l,r])
vector<int> lazy(4 * maxn + 1, 0);

// #ifdef HOME
// void print(int sze) {
// 	cerr <<
// "-------------------------------------------------------------------------------------------------\\n";
// 	cerr << "{ind, tree[ind], lazy[ind]}\\n";

// 	for (int i = 1; i <= sze; i++) {
// 		cerr << "{" << i << ", " << tree[i] << ", " << lazy[i] << "} ";
// 		if (__builtin_popcount(i + 1) == 1) cerr << endl;
// 	}
// 	cerr <<
// "\\n-------------------------------------------------------------------------------------------------\\n";
// }
// #else
// void print(int sze) {}
// #endif

void merge(int l, int r, int ind) {
  int mid((l + r) >> 1);
  int l1 = l, r1 = mid, l2 = mid + 1, r2 = r;
  int x = r2 - l2 + 1;
  Modint left = tree[2 * ind], right = tree[2 * ind + 1];

  tree[ind] = pw[x] * left + right;
  return;
}

void push(int l, int r, int ind) {
  if (lazy[ind] != 0) {
    int x = r - l + 1;
    tree[ind] = (pw[x] - 1) * INV9 * lazy[ind];

    if (l != r) {
      lazy[2 * ind] = lazy[ind];
      lazy[2 * ind + 1] = lazy[ind];
    }
    lazy[ind] = 0;
  }
}

void build(int l, int r, int ind) {
  if (l == r) {
    tree[ind] = 1;
    return;
  }

  int mid((l + r) >> 1);
  build(l, mid, 2 * ind);
  build(mid + 1, r, 2 * ind + 1);
  merge(l, r, ind);
}

void update(int ul, int ur, int uv, int l, int r, int ind) {
  push(l, r, ind);

  if (ur < l or r < ul)
    return;

  if (ul <= l and r <= ur) {
    lazy[ind] = uv;
    push(l, r, ind);
    return;
  }

  int mid((l + r) >> 1);
  update(ul, ur, uv, l, mid, 2 * ind);
  update(ul, ur, uv, mid + 1, r, 2 * ind + 1);
  merge(l, r, ind);
}

int main() {

  for (int i = 1; i <= maxn; i++)
    pw[i] = pw[i - 1] * 10;

  cin >> n >> q;

  build(1, n, 1);

  while (q--) {
    int l, r, d;
    cin >> l >> r >> d;
    update(l, r, d, 1, n, 1);

    cout << tree[1] << "\\n";
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <chrono>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

using namespace std;
struct _ {
  ios_base::Init i;
  _() { ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL); }
} _;

const int maxn = 2e5;
const int MOD = 998244353;

class Modint {
public:
  long long val;

  Modint(long long _val = 0) : val((_val + MOD) % MOD) {}

  Modint operator+(Modint other) { return Modint(val + other.val); }

  void operator+=(Modint other) {
    val += other.val;
    val %= MOD;
  }

  Modint operator-() { return Modint(MOD - val); }

  Modint operator-(Modint other) { return Modint(val + MOD - other.val); }

  void operator-=(Modint other) {
    val += MOD - other.val;
    val %= MOD;
  }

  Modint operator*(Modint other) { return Modint(val * other.val); }

  void operator*=(Modint other) {
    val *= other.val;
    val %= MOD;
  }

  bool operator==(Modint other) { return val == other.val; }

  bool operator!=(Modint other) { return val != other.val; }
};

Modint exp(Modint a, int k) {
  if (k == 0) {
    return Modint(1);
  } else if (k % 2 == 0) {
    Modint half = exp(a, k / 2);
    return half * half;
  } else {
    return a * exp(a, k - 1);
  }
}

Modint inv(Modint a) { return exp(a, MOD - 2); }

ostream &operator<<(ostream &out, Modint p) {
  out << p.val;
  return out;
}

// vector<int> a(maxn, 0);
int n, q;
vector<Modint> pw(maxn + 1, 1);
vector<Modint> tree(4 * maxn, 0); // update->[l,r]+=inc, query->sum([l,r])
vector<int> lazy(4 * maxn, 0);

// #ifdef HOME
// void print(int sze) {
// 	cerr <<
// "-------------------------------------------------------------------------------------------------\\n";
// 	cerr << "{ind, tree[ind], lazy[ind]}\\n";

// 	for (int i = 1; i <= sze; i++) {
// 		cerr << "{" << i << ", " << tree[i] << ", " << lazy[i] << "} ";
// 		if (__builtin_popcount(i + 1) == 1) cerr << endl;
// 	}
// 	cerr <<
// "\\n-------------------------------------------------------------------------------------------------\\n";
// }
// #else
// void print(int sze) {}
// #endif

void merge(int l, int r, int ind) {
  int mid((l + r) >> 1);
  int l1 = l, r1 = mid, l2 = mid + 1, r2 = r;
  int x = r2 - l2 + 1;
  Modint left = tree[2 * ind], right = tree[2 * ind + 1];

  tree[ind] = pw[x] * left + right;
  return;
}

void push(int l, int r, int ind) {
  if (lazy[ind] != 0) {
    // tree[ind] += (r - l + 1) * lazy[ind];
    int x = r - l + 1;
    tree[ind] = (pw[x] - 1) * inv(9) * lazy[ind];

    if (l != r) {
      lazy[2 * ind] = lazy[ind];
      lazy[2 * ind + 1] = lazy[ind];
    }
    // else a[l] = tree[ind];

    lazy[ind] = 0;
  }
}

void build(int l, int r, int ind) {
  if (l == r) {
    tree[ind] = 1;
    return;
  }

  int mid((l + r) >> 1);
  build(l, mid, 2 * ind);
  build(mid + 1, r, 2 * ind + 1);
  merge(l, r, ind);
}

void update(int ul, int ur, int uv, int l, int r, int ind) {
  push(l, r, ind);

  if (ur < l or r < ul)
    return;

  if (ul <= l and r <= ur) {
    lazy[ind] = uv;
    push(l, r, ind);
    return;
  }

  int mid((l + r) >> 1);
  update(ul, ur, uv, l, mid, 2 * ind);
  update(ul, ur, uv, mid + 1, r, 2 * ind + 1);
  merge(l, r, ind);
}

// int query(int ql, int qr, int l, int r, int ind) {
// 	push(l, r, ind);

// 	if (qr < l or r < ql) return 0;

// 	if (ql <= l and r <= qr) return tree[ind];

// 	int mid((l + r) >> 1);
// 	return merge(query(ql, qr, l, mid, 2 * ind), query(ql, qr, mid + 1, r, 2
// * ind + 1));
// }

int main() {

  cin >> n >> q;

  for (int i = 1; i <= maxn; i++)
    pw[i] = pw[i - 1] * 10;

  build(1, n, 1);

  while (q--) {
    int l, r, d;
    cin >> l >> r >> d;
    update(l, r, d, 1, n, 1);

    cout << tree[1] << "\\n";
  }

  return 0;
}