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

#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <vector>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double LD;
using namespace std;
const int INF = 2147483647;
const int INF2 = 0x3f3f3f3f;
const ll INF64 = 3e18;
const double INFD = 1e30;
const double EPS = 1e-10;
const double PI = acos(-1);
const int MOD = 998244353;
template <typename T> inline T read() {
  T X = 0, w = 0;
  char ch = 0;
  while (!isdigit(ch)) {
    w |= ch == '-';
    ch = getchar();
  }
  while (isdigit(ch))
    X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
  return w ? -X : X;
}
const int MAXN = 200005;
int n, m, k;
int dr[4] = {1, 0, -1, 0};
int dc[4] = {0, 1, 0, -1};
int dr2[8] = {1, 1, 1, -1, -1, -1, 0, 0};
int dc2[8] = {1, 0, -1, 1, 0, -1, 1, -1};
int CASE = 1;
int arr[MAXN];
int b[MAXN];
#define self nodes[p]
#define ls nodes[p << 1]
#define rs nodes[p << 1 | 1]
struct SegmentTree {
  struct Node {
    int cov, tag;
  };
  Node nodes[MAXN << 2];
  int tot;

  inline void modify(int l, int r, int p, int f) {
    self.tag += nodes[f].tag;
    self.cov += (r - l + 1) * nodes[f].tag;
  }

  inline void push_down(int l, int r, int p) {
    if (self.tag != 0) {
      int mid = (l + r) / 2;
      modify(l, mid, p << 1, p);
      modify(mid + 1, r, p << 1 | 1, p);
      self.tag = 0;
    }
  }
  void push_up(int p) { self.cov = ls.cov + rs.cov; }
  void update(int x, int y, int l, int r, int p, int v) {
    if (x <= l && y >= r) {
      self.cov += (r - l + 1) * v;
      self.tag += v;
      return;
    }
    push_down(l, r, p);
    int mid = (l + r) / 2;
    if (x <= mid)
      update(x, y, l, mid, p << 1, v);
    if (y > mid)
      update(x, y, mid + 1, r, p << 1 | 1, v);
    push_up(p);
  }
  int query(int x, int l, int r, int p) {
    if (l == r)
      return self.cov;
    int mid = (l + r) / 2;
    push_down(l, r, p);
    if (x <= mid)
      return query(x, l, mid, p << 1);
    else
      return query(x, mid + 1, r, p << 1 | 1);
  }
};

SegmentTree tree;
char text[MAXN];
int main() {
#ifdef LOCALLL
  freopen("in", "r", stdin);
  freopen("out", "w", stdout);
#endif
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &arr[i]);
    tree.update(max(1, i - arr[i]), min(n, i + arr[i]), 1, n, 1, 1);
  }
  for (int i = 0; i < min(m, 50); i++) {
    for (int j = 1; j <= n; j++) {
      b[j] = tree.query(j, 1, n, 1);
    }
    for (int j = 1; j <= n; j++) {
      tree.update(max(1, j - arr[j]), min(n, j + arr[j]), 1, n, 1, -1);
      arr[j] = b[j];
    }
    for (int j = 1; j <= n; j++) {
      tree.update(max(1, j - b[j]), min(n, j + b[j]), 1, n, 1, 1);
    }
  }
  for (int j = 1; j <= n; j++) {
    printf("%d ", b[j]);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <vector>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double LD;
using namespace std;
const int INF = 2147483647;
const int INF2 = 0x3f3f3f3f;
const ll INF64 = 3e18;
const double INFD = 1e30;
const double EPS = 1e-10;
const double PI = acos(-1);
const int MOD = 998244353;
template <typename T> inline T read() {
  T X = 0, w = 0;
  char ch = 0;
  while (!isdigit(ch)) {
    w |= ch == '-';
    ch = getchar();
  }
  while (isdigit(ch))
    X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
  return w ? -X : X;
}
const int MAXN = 200005;
int n, m, k;
int dr[4] = {1, 0, -1, 0};
int dc[4] = {0, 1, 0, -1};
int dr2[8] = {1, 1, 1, -1, -1, -1, 0, 0};
int dc2[8] = {1, 0, -1, 1, 0, -1, 1, -1};
int CASE = 1;
int arr[MAXN];
int b[MAXN];
#define self nodes[p]
#define ls nodes[p << 1]
#define rs nodes[p << 1 | 1]
struct SegmentTree {
  struct Node {
    int cov, tag;
  };
  Node nodes[MAXN << 2];
  int tot;

  inline void modify(int l, int r, int p, int f) {
    self.tag += nodes[f].tag;
    self.cov += (r - l + 1) * nodes[f].tag;
  }

  inline void push_down(int l, int r, int p) {
    if (self.tag != 0) {
      int mid = (l + r) / 2;
      modify(l, mid, p << 1, p);
      modify(mid + 1, r, p << 1 | 1, p);
      self.tag = 0;
    }
  }
  void push_up(int p) { self.cov = ls.cov + rs.cov; }
  void update(int x, int y, int l, int r, int p, int v) {
    if (x <= l && y >= r) {
      self.cov += (r - l + 1) * v;
      self.tag += v;
      return;
    }
    push_down(l, r, p);
    int mid = (l + r) / 2;
    if (x <= mid)
      update(x, y, l, mid, p << 1, v);
    if (y > mid)
      update(x, y, mid + 1, r, p << 1 | 1, v);
    push_up(p);
  }
  int query(int x, int l, int r, int p) {
    if (l == r)
      return self.cov;
    int mid = (l + r) / 2;
    push_down(l, r, p);
    if (x <= mid)
      return query(x, l, mid, p << 1);
    else
      return query(x, mid + 1, r, p << 1 | 1);
  }
};

SegmentTree tree;
char text[MAXN];
int main() {
#ifdef LOCALLL
  freopen("in", "r", stdin);
  freopen("out", "w", stdout);
#endif
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &arr[i]);
    tree.update(max(1, i - arr[i]), min(n, i + arr[i]), 1, n, 1, 1);
  }
  for (int i = 0; i < min(m, 100); i++) {
    for (int j = 1; j <= n; j++) {
      b[j] = tree.query(j, 1, n, 1);
    }
    for (int j = 1; j <= n; j++) {
      tree.update(max(1, j - arr[j]), min(n, j + arr[j]), 1, n, 1, -1);
      arr[j] = b[j];
    }
    for (int j = 1; j <= n; j++) {
      tree.update(max(1, j - b[j]), min(n, j + b[j]), 1, n, 1, 1);
    }
  }
  for (int j = 1; j <= n; j++) {
    printf("%d ", b[j]);
  }
  return 0;
}