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

// For higher stack size use g++ -O2 -std=c++11 -Wall -Wl,--stack=268435456
// a.cpp -o a.exe in cmd
#include <bits/stdc++.h>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#define ll long long
#define ld long double
#define vi vector<int>
#define vll vector<ll>
#define vvi vector<vi>
#define pii pair<int, int>
#define pll pair<long long, long long>
#define mod 998244353
#define inf 1000000000000000001;
#define all(c) c.begin(), c.end()
#define mp(x, y) make_pair(x, y)
#define mem(a, val) memset(a, val, sizeof(a))
#define eb emplace_back
#define pb push_back
#define f first
#define s second

using namespace std;

ll tree[5000000], lz[5000000], tree2[5000000];
ll tpow[300001], ninv;
int n;

ll power(ll a, ll b) // a is base, b is exponent
{
  if (b == 0)
    return 1;
  if (b == 1)
    return a;
  if (b % 2 == 1)
    return (power(a, b - 1) * a) % mod;
  ll q = power(a, b / 2);
  return (q * q) % mod;
}

void init() {
  tpow[0] = 1;
  for (int i = 1; i <= 300000; ++i) {
    tpow[i] = (tpow[i - 1] * 10) % mod;
  }
  ninv = power(9, mod - 2);
}

void build(int node, int l, int r) {
  lz[node] = -1;
  if (l == r) {
    tree[node] = 1;
    tree2[node] = tpow[n - r];
    // cout<<l<<" "<<r<<" "<<tree2[node]<<endl;

    return;
  }
  build(node * 2, l, (l + r) / 2);
  build(node * 2 + 1, (l + r) / 2 + 1, r);
  tree2[node] = (tree2[node * 2] + tree2[node * 2 + 1]) % mod;
  // cout<<node<<" "<<l<<" "<<r<<" "<<tree2[node]<<endl;
}

void update(int node, int l, int r, int i, int j, int x) {
  if (lz[node] != -1) {
    // cout<<"HELLO"<<endl;
    int zz = lz[node];
    int z = r - l + 1;
    // cout<<z<<" "<<tpow[z]<<" "<<ninv<<endl;
    tree[node] = zz;
    tree2[node] = (zz * (((tpow[z] - 1) * ninv) % mod)) % mod;
    tree2[node] = (tree2[node] * tpow[n - r]) % mod;
    if (l != r) {
      lz[node * 2] = lz[node];
      lz[node * 2 + 1] = lz[node];
    }
    lz[node] = -1;
  }
  if (j < l || r < i)
    return;
  if (i <= l && r <= j) {
    int z = r - l + 1;
    tree[node] = x;
    lz[node] = x;
    tree2[node] = (x * (((tpow[z] - 1) * ninv) % mod)) % mod;
    // cout<<tree2[node]<<endl;
    tree2[node] = (tree2[node] * tpow[n - r]) % mod;
    // cout<<z<<" "<<l<<"..."<<r<<" "<<tree2[node]<<" "<<i<<" "<<j<<endl;
    return;
  }
  update(node * 2, l, (l + r) / 2, i, j, x);
  update(node * 2 + 1, (l + r) / 2 + 1, r, i, j, x);
  tree2[node] = (tree2[node * 2] + tree2[node * 2 + 1]) % mod;
  // cout<<l<<"..."<<r<<" "<<tree2[node]<<" "<<i<<" "<<j<<endl;
}

ll query(int node, int l, int r, int i, int j) {
  if (lz[node] != -1) {
    // cout<<"HELLO"<<endl;
    int zz = lz[node];
    int z = r - l + 1;
    tree[node] = zz;
    tree2[node] = (zz * (((tpow[z] - 1) * ninv) % mod)) % mod;
    tree2[node] = (tree2[node] * tpow[n - r]) % mod;
    if (l != r) {
      lz[node * 2] = lz[node];
      lz[node * 2 + 1] = lz[node];
    }
    lz[node] = -1;
  }
  if (j < l || r < i)
    return 0;
  if (i <= l && r <= j) {
    return tree2[node];
  }
  ll q1 = query(node * 2, l, (l + r) / 2, i, j);
  ll q2 = query(node * 2 + 1, (l + r) / 2 + 1, r, i, j);
  return (q1 + q2) % mod; // Change for min/sum
}

int main() {
  std::ios::sync_with_stdio(false);
  int T;
  T = 1;
  // cin.ignore(); must be there when using getline(cin, s)
  while (T--) {
    init();
    int q, i, j, a, b, c, l, r;
    cin >> n >> q;
    build(1, 1, n);

    while (q--) {
      cin >> l >> r >> a;
      update(1, 1, n, l, r, a);
      cout << query(1, 1, n, 1, n) << endl;
    }
  }
  return 0;
}


Error: TLE

Fixed submission:

// For higher stack size use g++ -O2 -std=c++11 -Wall -Wl,--stack=268435456
// a.cpp -o a.exe in cmd
#include <bits/stdc++.h>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#define ll long long
#define ld long double
#define vi vector<int>
#define vll vector<ll>
#define vvi vector<vi>
#define pii pair<int, int>
#define pll pair<long long, long long>
#define mod 998244353
#define inf 1000000000000000001;
#define all(c) c.begin(), c.end()
#define mp(x, y) make_pair(x, y)
#define mem(a, val) memset(a, val, sizeof(a))
#define eb emplace_back
#define pb push_back
#define f first
#define s second

using namespace std;

ll tree[5000000], lz[5000000], tree2[5000000];
int n;

ll power(ll a, ll b) // a is base, b is exponent
{
  if (b == 0)
    return 1;
  if (b == 1)
    return a;
  if (b % 2 == 1)
    return (power(a, b - 1) * a) % mod;
  ll q = power(a, b / 2);
  return (q * q) % mod;
}

void build(int node, int l, int r) {
  lz[node] = -1;
  if (l == r) {
    tree[node] = 1;
    tree2[node] = power(10, n - l);
    // cout<<l<<" "<<r<<" "<<tree2[node]<<endl;

    return;
  }
  build(node * 2, l, (l + r) / 2);
  build(node * 2 + 1, (l + r) / 2 + 1, r);
  tree2[node] = (tree2[node * 2] + tree2[node * 2 + 1]) % mod;
  // cout<<node<<" "<<l<<" "<<r<<" "<<tree2[node]<<endl;
}

void update(int node, int l, int r, int i, int j, int x) {
  if (lz[node] != -1) {
    // cout<<"HELLO"<<endl;
    int zz = lz[node];
    int z = r - l + 1;
    tree[node] = zz;
    tree2[node] = (zz * (((power(10, z) - 1) * power(9, mod - 2)) % mod)) % mod;
    tree2[node] = (tree2[node] * power(10, n - r)) % mod;
    if (l != r) {
      lz[node * 2] = lz[node];
      lz[node * 2 + 1] = lz[node];
    }
    lz[node] = -1;
  }
  if (j < l || r < i)
    return;
  if (i <= l && r <= j) {
    int z = r - l + 1;
    tree[node] = x;
    lz[node] = x;
    tree2[node] = (x * (((power(10, z) - 1) * power(9, mod - 2)) % mod)) % mod;
    // cout<<tree2[node]<<endl;
    tree2[node] = (tree2[node] * power(10, n - r)) % mod;
    // cout<<z<<" "<<l<<"..."<<r<<" "<<tree2[node]<<" "<<i<<" "<<j<<endl;
    return;
  }
  update(node * 2, l, (l + r) / 2, i, j, x);
  update(node * 2 + 1, (l + r) / 2 + 1, r, i, j, x);
  tree2[node] = (tree2[node * 2] + tree2[node * 2 + 1]) % mod;
  // cout<<l<<"..."<<r<<" "<<tree2[node]<<" "<<i<<" "<<j<<endl;
}

ll query(int node, int l, int r, int i, int j) {
  if (lz[node] != -1) {
    int zz = lz[node];
    int z = r - l + 1;
    tree[node] = zz;
    tree2[node] = (zz * (((power(10, z) - 1) * power(9, mod - 2)) % mod)) % mod;
    tree2[node] = (tree2[node] * power(10, n - r)) % mod;
    if (l != r) {
      lz[node * 2] = lz[node];
      lz[node * 2 + 1] = lz[node];
    }
    lz[node] = -1;
  }
  if (j < l || r < i)
    return 0;
  if (i <= l && r <= j) {
    return tree2[node];
  }
  ll q1 = query(node * 2, l, (l + r) / 2, i, j);
  ll q2 = query(node * 2 + 1, (l + r) / 2 + 1, r, i, j);
  return (q1 + q2) % mod; // Change for min/sum
}

int main() {
  std::ios::sync_with_stdio(false);
  int T;
  T = 1;
  // cin.ignore(); must be there when using getline(cin, s)
  while (T--) {
    int q, i, j, a, b, c, l, r;
    cin >> n >> q;
    build(1, 1, n);
    while (q--) {
      cin >> l >> r >> a;
      update(1, 1, n, l, r, a);
      cout << query(1, 1, n, 1, n) << endl;
    }
  }
  return 0;
}