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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;

using VI = vector<int>;
using VVI = vector<VI>;

int main() {
  int N;
  int K;

  cin >> N >> K;

  vector<int> intensity(N);

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

  int nowTurn = 0;

  while (nowTurn < K) {
    vector<int> newIntensity(N);
    vector<int> intAcc(N + 1);

    for (int i = 0; i < N; ++i) {
      int minInt = max(0, i - intensity[i]);
      int maxInt = min(N, i + intensity[i] + 1);

      ++intAcc[minInt];
      --intAcc[maxInt];
    }

    int now = 0;
    bool converged = true;
    for (int i = 0; i < N; ++i) {
      now += intAcc[i];
      newIntensity[i] = now;
      if (newIntensity[i] != N) {
        converged = false;
      }
    }

    ++nowTurn;
    intensity = newIntensity;

    if (converged) {
      break;
    }
  }

  for (int i = 0; i < N; ++i) {
    if (i) {
      cout << " ";
    }
    cout << intensity[i];
  }

  cout << endl;

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <iostream>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;

using VI = vector<int>;
using VVI = vector<VI>;

struct SegmentTree {
  const int INVALID_VAL = -1;
  int val;
  int sum;
  int from;
  int to;
  SegmentTree *left;
  SegmentTree *right;

  SegmentTree(int treeSize) {
    from = 0;
    to = 1;
    sum = val = 0;

    while ((to - from) < treeSize) {
      to *= 2;
    }

    // cout << "GO " << from << " " << to << endl;

    left = right = nullptr;
  }

  SegmentTree(int pf, int pt) : from(pf), to(pt) {
    sum = val = 0;
    left = right = nullptr;
  }

  void propogate() {
    // int mid = (from + to) / 2;
    // if (left == nullptr) {
    //     left = new SegmentTree(from, mid);
    //     right = new SegmentTree(mid, to);
    // }

    left->val += this->val;
    right->val += this->val;
    this->val = 0;
  }

  void updateSegment(int f, int t, int val) {
    if (f >= t) {
      return;
    }

    if (f == from && t == to) {
      this->val += val;
      this->sum = this->val * (t - f);
      return;
    }

    int mid = (from + to) / 2;
    if (left == nullptr) {
      left = new SegmentTree(from, mid);
      right = new SegmentTree(mid, to);
    }

    propogate();

    left->updateSegment(f, min(t, mid), val);
    right->updateSegment(max(f, mid), t, val);

    this->sum = left->sum + right->sum;

    return;
  }

  int getVal(int f, int t) {
    if (f >= t) {
      return 0;
    }

    if (f == from && t == to) {
      this->sum = this->val * (t - f);
      return this->sum;
    }

    // cout << "GET VAL " << f << " " << t << " " << from << " " << to << endl;

    int mid = (from + to) / 2;

    if (left == nullptr) {
      left = new SegmentTree(from, mid);
      right = new SegmentTree(mid, to);
    }

    propogate();
    this->sum = 0;

    if (t > mid) {
      this->sum += right->getVal(max(f, mid), t);
    }

    if (f < mid) {
      this->sum += left->getVal(f, min(t, mid));
    }

    return this->sum;
  }
};

int main() {
  int N;
  int K;

  cin >> N >> K;

  vector<int> intensity(N);
  SegmentTree *st = new SegmentTree(N);

  for (int i = 0; i < N; ++i) {
    cin >> intensity[i];
    st->updateSegment(i, i + 1, intensity[i]);
  }

  // cerr << "DEBUG 1" << endl;

  for (int k = 0; k < K; ++k) {
    SegmentTree *nst = new SegmentTree(N);
    bool allFilled = true;

    for (int i = 0; i < N; ++i) {
      int curVal = st->getVal(i, i + 1);
      if (curVal != N) {
        allFilled = false;
      }

      int maxVal = min(N - 1, i + curVal);
      int minVal = max(0, i - curVal);

      // cout << "UPDATE " << minVal << " " << i << " " << maxVal << endl;

      nst->updateSegment(minVal, maxVal + 1, 1);
    }

    if (allFilled) {
      break;
    }

    st = nst;
  }

  for (int i = 0; i < N; ++i) {
    if (i) {
      cout << " ";
    }
    int curVal = st->getVal(i, i + 1);
    cout << curVal;
  }

  cout << endl;

  return 0;
}