Problem p02549 (C++)

Buggy submission (status: Runtime Error):
/*
Dont BLUNDER
*/

// #pragma GCC optimize("O3")
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("Ofast")
// #pragma GCC optimization ("unroll-loops")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <ctime>
#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 <unordered_set>
#include <vector>
using namespace std;
/*#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;


 */
// #define d long double
#define int long long
#define pii pair<int, int>
#define pb push_back
#define endl '\n'
#define pi acos(-1)

#define init(x, a) memset(x, a, sizeof(x))
#define all(c) c.begin(), c.end()
int const mod1 = 998244353;
int const mod = 1000000007;
#define bitcount(x) __builtin_popcountll(x)
#define l first
#define r second
const int inf = LLONG_MAX;
int toint(const string &s) {
  stringstream ss;
  ss << s;
  int x;
  ss >> x;
  return x;
}
string tostring(int number) {
  stringstream ss;
  ss << number;
  return ss.str();
}
#define trace1(x) cerr << #x << ": " << x << endl
#define trace2(x, y) cerr << #x << ": " << x << " | " << #y << ": " << y << endl
#define trace3(x, y, z)                                                        \
  cerr << #x << ":" << x << " | " << #y << ": " << y << " | " << #z << ": "    \
       << z << endl
#define haha                                                                   \
  ios_base::sync_with_stdio(0);                                                \
  cin.tie(0);                                                                  \
  cout.tie(0);
// * Using PBDS *
/*typedef tree<int, null_type, less<int>, rb_tree_tag,
            tree_order_statistics_node_update>
               os; */

struct cmp {
  bool operator()(pii a, pii b) { return (a.l < b.l); }
};

int modexp(int x, int n) {
  if (n == 0) {
    return 1;
  } else if (n & 1) {
    return (modexp((x * x) % mod, n / 2) % mod * x % mod) % mod;
  } else {
    return (modexp((x * x) % mod, n / 2) % mod);
  }
}

int modinv(int n) { return modexp(n, mod - 2); }

int gcd(int a, int b) {
  if (b == 0) {
    return a;
  }
  return gcd(b, a % b);
}

int segm_tree[400001];
int a[200001];

void recalculate(int node) {
  // calculate the solution for the current segment,
  // considering the sons are correctly solved
  segm_tree[node] = (segm_tree[2 * node] + segm_tree[2 * node + 1]) % mod1;
}

void build(int node, int left,
           int right) { //"node" is the index in the array, while "left"
  // and "right" are the ends of the current segment
  if (left == right) {
    segm_tree[node] = a[left]; // we are in a leaf node
  } else {
    int middle = (left + right) / 2;
    build(2 * node, left, middle);
    build(2 * node + 1, middle + 1, right);
    recalculate(node);
  }
}

void update(int node, int left, int right, int x, int y) {
  if (left == right) { // we are in the xth leaf
    segm_tree[node] = y;
  } else {
    int middle = (left + right) / 2;
    if (x <= middle) { // we need to update the left son
      update(2 * node, left, middle, x, y);
    } else {
      update(2 * node + 1, middle + 1, right, x, y);
    }
    // after updating said son, recalculate the current segment
    recalculate(node);
  }
}

int query(int node, int left, int right, int x, int y) {

  if (y < left or right < x) {
    // range represented by a node is completely outside the given range
    return 0;
  }
  if (x <= left && right <= y) {
    // the segment of "node" is completely included in the query
    return segm_tree[node];
  } else {
    // int answer = -10000;
    int middle = (left + right) / 2;
    int p1 = query(2 * node, left, middle, x, y);
    int p2 = query(2 * node + 1, middle + 1, right, x, y);
    // we would not have entered this function if (x, y) and (left, right) had
    // nothing in common, so there is no risk of answer returning -Infinity
    // here, as either the left or the right son would update it
    return (p1 + p2) % mod1;
  }
}

signed main() {
  haha
#ifndef ONLINE_JUDGE

      freopen("inp.txt", "r", stdin);

  freopen("out1.txt", "w", stdout);
#endif
  vector<pii> v;
  int n, k;
  cin >> n >> k;
  int ans = 0;

  init(a, 0);

  a[1] = 1;
  build(1, 1, n);
  for (int i = 0; i < k; i++) {
    int x;
    int y;
    cin >> x >> y;
    v.pb({x, y});
  }
  for (int i = 2; i <= n; i++) {
    int temp = 0;
    for (auto x : v) {
      int l = x.first;
      int r = x.second;
      if (i - l >= 1) {
        int qr = i - l;
        int ql = max(1ll, i - r);
        temp += query(1, 1, n, ql, qr);
        temp %= mod1;
      }
    }
    a[i] = temp;
    update(1, 1, n, i, temp);
  }

  cout << a[n];
}


Fixed submission:
/*
Dont BLUNDER
*/

// #pragma GCC optimize("O3")
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("Ofast")
// #pragma GCC optimization ("unroll-loops")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <ctime>
#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 <unordered_set>
#include <vector>
using namespace std;
/*#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;


 */
// #define d long double
#define int long long
#define pii pair<int, int>
#define pb push_back
#define endl '\n'
#define pi acos(-1)

#define init(x, a) memset(x, a, sizeof(x))
#define all(c) c.begin(), c.end()
int const mod1 = 998244353;
int const mod = 1000000007;
#define bitcount(x) __builtin_popcountll(x)
#define l first
#define r second
const int inf = LLONG_MAX;
int toint(const string &s) {
  stringstream ss;
  ss << s;
  int x;
  ss >> x;
  return x;
}
string tostring(int number) {
  stringstream ss;
  ss << number;
  return ss.str();
}
#define trace1(x) cerr << #x << ": " << x << endl
#define trace2(x, y) cerr << #x << ": " << x << " | " << #y << ": " << y << endl
#define trace3(x, y, z)                                                        \
  cerr << #x << ":" << x << " | " << #y << ": " << y << " | " << #z << ": "    \
       << z << endl
#define haha                                                                   \
  ios_base::sync_with_stdio(0);                                                \
  cin.tie(0);                                                                  \
  cout.tie(0);
// * Using PBDS *
/*typedef tree<int, null_type, less<int>, rb_tree_tag,
            tree_order_statistics_node_update>
               os; */

struct cmp {
  bool operator()(pii a, pii b) { return (a.l < b.l); }
};

int modexp(int x, int n) {
  if (n == 0) {
    return 1;
  } else if (n & 1) {
    return (modexp((x * x) % mod, n / 2) % mod * x % mod) % mod;
  } else {
    return (modexp((x * x) % mod, n / 2) % mod);
  }
}

int modinv(int n) { return modexp(n, mod - 2); }

int gcd(int a, int b) {
  if (b == 0) {
    return a;
  }
  return gcd(b, a % b);
}

int segm_tree[600001];
int a[200001];

void recalculate(int node) {
  // calculate the solution for the current segment,
  // considering the sons are correctly solved
  segm_tree[node] = (segm_tree[2 * node] + segm_tree[2 * node + 1]) % mod1;
}

void build(int node, int left,
           int right) { //"node" is the index in the array, while "left"
  // and "right" are the ends of the current segment
  if (left == right) {
    segm_tree[node] = a[left]; // we are in a leaf node
  } else {
    int middle = (left + right) / 2;
    build(2 * node, left, middle);
    build(2 * node + 1, middle + 1, right);
    recalculate(node);
  }
}

void update(int node, int left, int right, int x, int y) {
  if (left == right) { // we are in the xth leaf
    segm_tree[node] = y;
  } else {
    int middle = (left + right) / 2;
    if (x <= middle) { // we need to update the left son
      update(2 * node, left, middle, x, y);
    } else {
      update(2 * node + 1, middle + 1, right, x, y);
    }
    // after updating said son, recalculate the current segment
    recalculate(node);
  }
}

int query(int node, int left, int right, int x, int y) {

  if (y < left or right < x) {
    // range represented by a node is completely outside the given range
    return 0;
  }
  if (x <= left && right <= y) {
    // the segment of "node" is completely included in the query
    return segm_tree[node];
  } else {
    // int answer = -10000;
    int middle = (left + right) / 2;
    int p1 = query(2 * node, left, middle, x, y);
    int p2 = query(2 * node + 1, middle + 1, right, x, y);
    // we would not have entered this function if (x, y) and (left, right) had
    // nothing in common, so there is no risk of answer returning -Infinity
    // here, as either the left or the right son would update it
    return (p1 + p2) % mod1;
  }
}

signed main() {
  haha
#ifndef ONLINE_JUDGE

      freopen("inp.txt", "r", stdin);

  freopen("out1.txt", "w", stdout);
#endif
  vector<pii> v;
  int n, k;
  cin >> n >> k;
  int ans = 0;

  init(a, 0);

  a[1] = 1;
  build(1, 1, n);
  for (int i = 0; i < k; i++) {
    int x;
    int y;
    cin >> x >> y;
    v.pb({x, y});
  }
  for (int i = 2; i <= n; i++) {
    int temp = 0;
    for (auto x : v) {
      int l = x.first;
      int r = x.second;
      if (i - l >= 1) {
        int qr = i - l;
        int ql = max(1ll, i - r);
        temp += query(1, 1, n, ql, qr);
        temp %= mod1;
      }
    }
    a[i] = temp;
    update(1, 1, n, i, temp);
  }

  cout << a[n];
}