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

#include <bits/stdc++.h>

using namespace std;

#define REP(i, a, b) for (int i = a; i < (int)b; i++)
#define rep(i, n) REP(i, 0, n)
#define all(c) (c).begin(), (c).end()
#define zero(a) memset(a, 0, sizeof a)
#define minus(a) memset(a, -1, sizeof a)
#define watch(a)                                                               \\
  { std::cout << #a << " = " << a << "\\n"; }
template <class T1, class T2> inline bool minimize(T1 &a, T2 b) {
  return b < a && (a = b, 1);
}
template <class T1, class T2> inline bool maximize(T1 &a, T2 b) {
  return a < b && (a = b, 1);
}
template <class T, class V> istream &operator>>(istream &ist, pair<T, V> &p) {
  return ist >> p.first >> p.second;
}
template <class T> ostream &operator<<(ostream &ost, pair<T, T> &p) {
  return ost << p.first << ", " << p.second;
}
template <class T> istream &operator>>(istream &ist, vector<T> &vs) {
  for (auto &e : vs)
    ist >> e;
  return ist;
}

typedef long long ll;
int const inf = INT_MAX / 2;

int main() {
  int N, K;
  cin >> N >> K;
  vector<int> A(N);
  cin >> A;
  rep(_, min(K, 50)) {
    vector<int> acc(N + 1);
    rep(i, N) {
      acc[max(0, i - A[i])]++;
      acc[min(N, i + A[i] + 1)]--;
    }
    REP(i, 1, N + 1) { acc[i] += acc[i - 1]; }
    rep(i, N) { A[i] = acc[i]; }
  }
  rep(i, N) {
    if (i)
      cout << " ";
    cout << A[i];
  }
  cout << "\\n";
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#define REP(i, a, b) for (int i = a; i < (int)b; i++)
#define rep(i, n) REP(i, 0, n)
#define all(c) (c).begin(), (c).end()
#define zero(a) memset(a, 0, sizeof a)
#define minus(a) memset(a, -1, sizeof a)
#define watch(a)                                                               \\
  { std::cout << #a << " = " << a << "\\n"; }
template <class T1, class T2> inline bool minimize(T1 &a, T2 b) {
  return b < a && (a = b, 1);
}
template <class T1, class T2> inline bool maximize(T1 &a, T2 b) {
  return a < b && (a = b, 1);
}
template <class T, class V> istream &operator>>(istream &ist, pair<T, V> &p) {
  return ist >> p.first >> p.second;
}
template <class T> ostream &operator<<(ostream &ost, pair<T, T> &p) {
  return ost << p.first << ", " << p.second;
}
template <class T> istream &operator>>(istream &ist, vector<T> &vs) {
  for (auto &e : vs)
    ist >> e;
  return ist;
}

typedef long long ll;
int const inf = INT_MAX / 2;

// Verified: AOJ2644 Longest Match (min, max) DSL_2_G (sum)
enum query_type { min_query, max_query, sum_query };

template <class T> struct segtree {
  int N, K;
  vector<T> dat, sum;
  function<T(T, T)> func;
  T ngvalue;
  query_type qtype;

  void init(int n, function<T(T, T)> &&f, T ng, query_type type) {
    K = 0, N = 1;
    while (N < n)
      K++, N <<= 1;
    dat.assign(2 * N - 1, 0);
    sum.assign(2 * N - 1, 0);
    func = std::move(f);
    ngvalue = ng;
    qtype = type;
  }

  segtree() = default;

  segtree(int n, query_type qtype) {
    if (qtype == min_query) {
      init(
          n, [](T a, T b) { return min(a, b); }, numeric_limits<T>::max(),
          max_query);
    } else if (qtype == max_query) {
      init(
          n, [](T a, T b) { return max(a, b); }, numeric_limits<T>::min(),
          min_query);
    } else if (qtype == sum_query) {
      init(
          n, [](T a, T b) { return a + b; }, 0, sum_query);
    } else {
      runtime_error("no matching query type");
    }
  }

  void add(int i, T x) { add(i, i + 1, x); }

  void add(int a, int b, T x) { add(a, b, x, 0, 0, N); }

  T add(int a, int b, T x, int k, int l, int r) {
    if (b <= l || r <= a)
      return dat[k];
    if (a <= l && r <= b) {
      sum[k] += x;
      return dat[k] += x * (qtype == sum_query ? r - l : 1);
    }
    int m = (l + r) / 2;
    return dat[k] = func(add(a, b, x, 2 * k + 1, l, m),
                         add(a, b, x, 2 * k + 2, m, r)) +
                    sum[k] * (qtype == sum_query ? r - l : 1);
  }

  T operator()(int a, int b) { return query(a, b, 0, 0, N); }

  T query(int a, int b, int k, int l, int r) {
    if (b <= l || r <= a)
      return ngvalue;
    if (a <= l && r <= b)
      return dat[k];
    int m = (l + r) / 2;
    return func(query(a, b, 2 * k + 1, l, m), query(a, b, 2 * k + 2, m, r)) +
           sum[k] *
               (qtype == sum_query ? (b < r ? b : r) - (a < l ? l : a) : 1);
  }
};

int main() {
  int N, K;
  cin >> N >> K;
  segtree<int> st(N, min_query);
  rep(i, N) {
    int A;
    cin >> A;
    st.add(i, A);
  }
  rep(_, K) {
    segtree<int> next_st(N, min_query);
    rep(i, N) {
      int A = st(i, i + 1);
      next_st.add(i - A, i + A + 1, 1);
    }
    bool no_change = 1;
    rep(i, N) {
      if (st(i, i + 1) != next_st(i, i + 1)) {
        no_change = 0;
        break;
      }
    }
    if (no_change) {
      break;
    }
    st = std::move(next_st);
  }
  rep(i, N) {
    if (i)
      cout << " ";
    cout << st(i, i + 1);
  }
  cout << "\\n";
}