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

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

int main(void) {
  long long N, K;
  cin >> N >> K;
  vector<long long> A(N, 0);

  for (long long i = 0; i < N; i++) {
    cin >> A[i];
  }

  for (long long i = 0; i < K; i++) {
    vector<long long> imos(N + 1, 0);
    for (long long j = 0; j < N; j++) {
      imos[max(0LL, j - A[j])]++;
      imos[min(j + A[j] + 1, N)]--;
    }
    for (long long j = 1; j < N + 1; j++) {
      imos[j] += imos[j - 1];
    }

    bool is_same = true;
    for (long long j = 0; j < N; j++) {
      is_same &= A[j] == imos[j];
    }
    if (is_same)
      break;

    for (long long j = 0; j < N; j++) {
      A[j] = imos[j];
    }
  }

  for (int i = 0; i < N; i++) {
    cout << A[i] << " \\n"[i == N - 1];
  }
  return 0;
}

Error: TLE

Fixed submission:

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

struct LazySegmentTree {
private:
  int n;
  vector<long long> node, lazy;

public:
  LazySegmentTree(vector<long long> v) {
    int sz = (int)v.size();
    n = 1;
    while (n < sz)
      n *= 2;
    node.resize(2 * n - 1);
    lazy.resize(2 * n - 1, 0);

    for (int i = 0; i < sz; i++)
      node[i + n - 1] = v[i];
    for (int i = n - 2; i >= 0; i--)
      node[i] = node[i * 2 + 1] + node[i * 2 + 2];
  }

  // k 番目のノードについて遅延評価を行う
  void eval(int k, int l, int r) {
    // 遅延配列が空でない場合、自ノード及び子ノードへの
    // 値の伝播が起こる
    if (lazy[k] != 0) {
      node[k] += lazy[k];

      // 最下段かどうかのチェックをしよう
      // 子ノードは親ノードの 1/2 の範囲であるため、
      // 伝播させるときは半分にする
      if (r - l > 1) {
        lazy[2 * k + 1] += lazy[k] / 2;
        lazy[2 * k + 2] += lazy[k] / 2;
      }

      // 伝播が終わったので、自ノードの遅延配列を空にする
      lazy[k] = 0;
    }
  }
  void add(int a, int b, long long x, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;

    // k 番目のノードに対して遅延評価を行う
    eval(k, l, r);

    // 範囲外なら何もしない
    if (b <= l || r <= a)
      return;

    // 完全に被覆しているならば、遅延配列に値を入れた後に評価
    if (a <= l && r <= b) {
      lazy[k] += (r - l) * x;
      eval(k, l, r);
    }

    // そうでないならば、子ノードの値を再帰的に計算して、
    // 計算済みの値をもらってくる
    else {
      add(a, b, x, 2 * k + 1, l, (l + r) / 2);
      add(a, b, x, 2 * k + 2, (l + r) / 2, r);
      node[k] = node[2 * k + 1] + node[2 * k + 2];
    }
  }
  long long getsum(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;
    if (b <= l || r <= a)
      return 0;

    // 関数が呼び出されたら評価！
    eval(k, l, r);
    if (a <= l && r <= b)
      return node[k];
    long long vl = getsum(a, b, 2 * k + 1, l, (l + r) / 2);
    long long vr = getsum(a, b, 2 * k + 2, (l + r) / 2, r);
    return vl + vr;
  }
};

int main(void) {
  long long N, K;
  cin >> N >> K;
  vector<long long> A(N, 0);
  LazySegmentTree lst(A);

  for (long long i = 0; i < N; i++) {
    cin >> A[i];
    lst.add(max(0LL, i - A[i]), min(i + A[i] + 1, N), 1);
  }

  for (long long i = 0; i < K; i++) {
    vector<long long> sums(N);
    bool is_same = true;
    for (long long j = 0; j < N; j++) {
      sums[j] = lst.getsum(j, j + 1);
      is_same &= sums[j] == A[j];
    }
    if (is_same)
      break;
    for (long long j = 0; j < N; j++) {
      lst.add(max(0LL, j - A[j]), min(j + A[j] + 1, N), -1);
      lst.add(max(0LL, j - sums[j]), min(j + sums[j] + 1, N), 1);
      A[j] = sums[j];
    }
  }

  for (int i = 0; i < N; i++) {
    cout << A[i] << " \\n"[i == N - 1];
  }
  return 0;
}