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

#include <bits/stdc++.h>
using namespace std;

const long long MOD = 998244353;
using ll = long long;

template <typename T> class LazySegmentTree {
  //[l, r)半開区間を扱う
private:
  std::vector<T> node, lazy;

  T f_ide; // 演算fの単位元
  T g_ide; // 演算gの単位元

  int size;

public:
  LazySegmentTree(int n, T f_ide, T g_ide) : f_ide(f_ide), g_ide(g_ide) {
    init(n);
  }
  void init(int n) {
    size = 1;
    while (size < n)
      size *= 2;
    node = std::vector<T>(2 * size - 1, f_ide);
    lazy = std::vector<T>(2 * size - 1, g_ide);
  }
  void eval(int k, int l, int r) {
    node[k] = g(node[k], pow(lazy[k], r - l));

    if (r - l >= 2) {
      lazy[2 * k + 1] = g(lazy[2 * k + 1], lazy[k]);
      lazy[2 * k + 2] = g(lazy[2 * k + 2], lazy[k]);
    }

    lazy[k] = g_ide;
  }
  ll f(ll l, ll r) { return (l + r) % MOD; }
  ll g(ll l, ll r) { return (l + r) % MOD; }
  ll pow(ll x, ll y) { return (x * y) % MOD; }
  void update(int a, int b, T x, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = size;
    if (r <= a || b <= l)
      return;

    if (a <= l && r <= b) {
      lazy[k] = g(lazy[k], x);
      eval(k, l, r);
    } else {
      update(a, b, x, 2 * k + 1, l, (l + r) / 2);
      update(a, b, x, 2 * k + 2, (l + r) / 2, r);
      eval(2 * k + 1, l, (l + r) / 2);
      eval(2 * k + 2, (l + r) / 2, r);

      node[k] = f(node[2 * k + 1], node[2 * k + 2]);
    }
  }
  T get(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = size;
    if (r <= a || b <= l)
      return f_ide;

    eval(k, l, r);

    if (a <= l && r <= b) {
      return node[k];
    } else {
      T result_left = get(a, b, 2 * k + 1, l, (l + r) / 2);
      T result_right = get(a, b, 2 * k + 2, (l + r) / 2, r);
      return f(result_left, result_right);
    }
  }
};
/*
int main(){
    int n,q;std::cin >> n >> q;
    std::function<long long(long long, long long)> f = [](long long a, long long
b){ return a + b;
    };
    auto g = f;
    LazySegmentTree<long long> Seg(n, f, g, 0, 0);
    while(q--){
        int a;std::cin >> a;
        if(a == 0){
            int s,t,x;
            std::cin >> s >> t >> x;
            Seg.update(s - 1, t, x);
        }else{
            int s,t;
            std::cin >> s >> t;
            std::cout<<Seg.get(s - 1, t)<<std::endl;
        }
    }
}
*/

void solve(long long N, long long K, std::vector<long long> L,
           std::vector<long long> R) {

  LazySegmentTree<long long> Seg(N, 0LL, 0LL);
  Seg.update(0, 1, 1);
  for (int i = 0; i < N; i++) {
    for (int k = 0; k < K; k++) {
      ll l = i + L[k];
      ll r = i + R[k] + 1;
      ll x = Seg.get(i, i + 1);
      if (l >= N) {
        continue;
      }
      Seg.update(l, min(r, N), x);
    }
  }
  cout << Seg.get(N - 1, N) << endl;
}

int main() {
  long long N;
  scanf("%lld", &N);
  long long K;
  scanf("%lld", &K);
  std::vector<long long> L(K);
  std::vector<long long> R(K);
  for (int i = 0; i < K; i++) {
    scanf("%lld", &L[i]);
    scanf("%lld", &R[i]);
  }
  solve(N, K, std::move(L), std::move(R));
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

const long long MOD = 998244353;
using ll = long long;

template <typename T> class LazySegmentTree {
  //[l, r)半開区間を扱う
private:
  std::vector<T> node, lazy;
  std::function<T(T, T)> f; // 取得の演算
  std::function<T(T, T)> g; // 更新の演算
  std::function<T(T, int)> pow; // 更新の演算をk回作用させたときの結果

  T f_ide; // 演算fの単位元
  T g_ide; // 演算gの単位元

  int size;

public:
  LazySegmentTree(int n, std::function<T(T, T)> f, std::function<T(T, T)> g,
                  T f_ide, T g_ide)
      : f(f), g(g), f_ide(f_ide), g_ide(g_ide) {
    init(n);
    pow = [=](T a, int k) {
      T ans = g_ide;
      while (k > 0) {
        if (k & 1)
          ans = g(ans, a);
        a = g(a, a);
        k >>= 1;
      }
      return ans;
    };
  }
  LazySegmentTree(int n, std::function<T(T, T)> f, std::function<T(T, T)> g,
                  std::function<T(T, int)> pow, T f_ide, T g_ide)
      : f(f), g(g), pow(pow), f_ide(f_ide), g_ide(g_ide) {
    init(n);
  }
  void init(int n) {
    size = 1;
    while (size < n)
      size *= 2;
    node = std::vector<T>(2 * size - 1, f_ide);
    lazy = std::vector<T>(2 * size - 1, g_ide);
  }
  void eval(int k, int l, int r) {
    node[k] = g(node[k], pow(lazy[k], r - l));

    if (r - l >= 2) {
      lazy[2 * k + 1] = g(lazy[2 * k + 1], lazy[k]);
      lazy[2 * k + 2] = g(lazy[2 * k + 2], lazy[k]);
    }

    lazy[k] = g_ide;
  }
  void update(int a, int b, T x, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = size;
    if (r <= a || b <= l)
      return;

    if (a <= l && r <= b) {
      lazy[k] = g(lazy[k], x);
      eval(k, l, r);
    } else {
      update(a, b, x, 2 * k + 1, l, (l + r) / 2);
      update(a, b, x, 2 * k + 2, (l + r) / 2, r);
      eval(2 * k + 1, l, (l + r) / 2);
      eval(2 * k + 2, (l + r) / 2, r);

      node[k] = f(node[2 * k + 1], node[2 * k + 2]);
    }
  }
  T get(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = size;
    if (r <= a || b <= l)
      return f_ide;

    eval(k, l, r);

    if (a <= l && r <= b) {
      return node[k];
    } else {
      T result_left = get(a, b, 2 * k + 1, l, (l + r) / 2);
      T result_right = get(a, b, 2 * k + 2, (l + r) / 2, r);
      return f(result_left, result_right);
    }
  }
};
/*
int main(){
    int n,q;std::cin >> n >> q;
    std::function<long long(long long, long long)> f = [](long long a, long long
b){ return a + b;
    };
    auto g = f;
    LazySegmentTree<long long> Seg(n, f, g, 0, 0);
    while(q--){
        int a;std::cin >> a;
        if(a == 0){
            int s,t,x;
            std::cin >> s >> t >> x;
            Seg.update(s - 1, t, x);
        }else{
            int s,t;
            std::cin >> s >> t;
            std::cout<<Seg.get(s - 1, t)<<std::endl;
        }
    }
}
*/

void solve(long long N, long long K, std::vector<long long> L,
           std::vector<long long> R) {
  std::function<long long(long long, long long)> f =
      [](long long a, long long b) { return (a + b) % MOD; };
  std::function<long long(long long, int)> pow = [](long long a, int b) {
    return (a * b) % MOD;
  };
  auto g = f;
  LazySegmentTree<long long> Seg(N, f, g, pow, 0, 0);
  Seg.update(0, 1, 1);
  for (int i = 0; i < N; i++) {
    for (int k = 0; k < K; k++) {
      ll l = i + L[k];
      ll r = i + R[k] + 1;
      ll x = Seg.get(i, i + 1);
      if (l >= N) {
        continue;
      }
      Seg.update(l, min(r, N), x);
    }
  }
  cout << Seg.get(N - 1, N) << endl;
}

int main() {
  long long N;
  scanf("%lld", &N);
  long long K;
  scanf("%lld", &K);
  std::vector<long long> L(K);
  std::vector<long long> R(K);
  for (int i = 0; i < K; i++) {
    scanf("%lld", &L[i]);
    scanf("%lld", &R[i]);
  }
  solve(N, K, std::move(L), std::move(R));
  return 0;
}