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

#include <bits/stdc++.h>

using namespace std;

#define pb push_back
#define pf push_front
#define pob pop_back
#define pof pop_front
#define mp make_pair
#define fi first
#define se second

typedef long long lli;
typedef pair<int, int> ii;
typedef pair<lli, lli> ll;

lli n, h[800005], v[800005], lh[800005], lv[800005];

lli queryh(lli pos, lli l, lli r, lli x) {
  lli m = (l + r) / 2;
  if (lh[pos] < n) {
    h[pos] = min(h[pos], lh[pos]);
    if (l < r) {
      lh[(2 * pos) + 1] = min(lh[(2 * pos) + 1], lh[pos]);
      lh[(2 * pos) + 2] = min(lh[(2 * pos) + 2], lh[pos]);
    }
    lh[pos] = n;
  }
  if (l == r)
    return h[pos];
  if (x > m)
    return queryh((2 * pos) + 2, m + 1, r, x);
  return queryh((2 * pos) + 1, l, m, x);
}

lli queryv(lli pos, lli l, lli r, lli x) {
  lli m = (l + r) / 2;
  if (lv[pos] < n) {
    v[pos] = min(v[pos], lv[pos]);
    if (l < r) {
      lv[(2 * pos) + 1] = min(lv[(2 * pos) + 1], lv[pos]);
      lv[(2 * pos) + 2] = min(lv[(2 * pos) + 2], lv[pos]);
    }
    lv[pos] = n;
  }
  if (l == r)
    return v[pos];
  if (x > m)
    return queryv((2 * pos) + 2, m + 1, r, x);
  return queryv((2 * pos) + 1, l, m, x);
}

void updateh(lli pos, lli l, lli r, lli ql, lli qr, lli x) {
  lli m = (l + r) / 2;
  if (lh[pos] < n) {
    h[pos] = min(h[pos], lh[pos]);
    if (l < r) {
      lh[(2 * pos) + 1] = min(lh[(2 * pos) + 1], lh[pos]);
      lh[(2 * pos) + 2] = min(lh[(2 * pos) + 2], lh[pos]);
    }
    lh[pos] = n;
  }
  if ((r < ql) || (l > qr))
    return;
  if ((ql <= l) && (r <= qr)) {
    h[pos] = min(h[pos], x);
    if (l < r) {
      lh[(2 * pos) + 1] = min(lh[(2 * pos) + 1], x);
      lh[(2 * pos) + 2] = min(lh[(2 * pos) + 2], x);
    }
    return;
  }
  if (l < r) {
    updateh((2 * pos) + 1, l, m, ql, qr, x);
    updateh((2 * pos) + 2, m + 1, r, ql, qr, x);
  }
}

void updatev(lli pos, lli l, lli r, lli ql, lli qr, lli x) {
  lli m = (l + r) / 2;
  if (lv[pos] < n) {
    v[pos] = min(v[pos], lv[pos]);
    if (l < r) {
      lv[(2 * pos) + 1] = min(lv[(2 * pos) + 1], lv[pos]);
      lv[(2 * pos) + 2] = min(lv[(2 * pos) + 2], lv[pos]);
    }
    lv[pos] = n;
  }
  if ((r < ql) || (l > qr))
    return;
  if ((ql <= l) && (r <= qr)) {
    v[pos] = min(v[pos], x);
    if (l < r) {
      lv[(2 * pos) + 1] = min(lv[(2 * pos) + 1], x);
      lv[(2 * pos) + 2] = min(lv[(2 * pos) + 2], x);
    }
    return;
  }
  if (l < r) {
    updatev((2 * pos) + 1, l, m, ql, qr, x);
    updatev((2 * pos) + 2, m + 1, r, ql, qr, x);
  }
}

int main() {
  lli q, ans, a, b;
  scanf("%lld %lld", &n, &q);
  ans = (n - 2) * (n - 2);
  for (int i = 0; i < 800001; i++)
    h[i] = v[i] = lh[i] = lv[i] = n;
  while (q--) {
    scanf("%lld %lld", &a, &b);
    if (a == 1) {
      a = queryh(0, 2, n - 1, b);
      updatev(0, 2, n - 1, 2, a - 1, b);
    } else {
      a = queryv(0, 2, n - 1, b);
      updateh(0, 2, n - 1, 2, a - 1, b);
    }
    ans -= (a - 2);
  }
  printf("%lld\\n", ans);
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#define pb push_back
#define pf push_front
#define pob pop_back
#define pof pop_front
#define mp make_pair
#define fi first
#define se second

typedef long long lli;
typedef pair<int, int> ii;
typedef pair<lli, lli> ll;

lli n, h[800005], v[800005], lh[800005], lv[800005];

lli queryh(lli pos, lli l, lli r, lli x) {
  lli m = (l + r) / 2;
  if (lh[pos] > 0) {
    h[pos] = min(h[pos], lh[pos]);
    if (l < r) {
      lh[(2 * pos) + 1] = min(lh[(2 * pos) + 1], lh[pos]);
      lh[(2 * pos) + 2] = min(lh[(2 * pos) + 2], lh[pos]);
    }
    lh[pos] = 0;
  }
  if (l == r)
    return h[pos];
  if (x > m)
    return queryh((2 * pos) + 2, m + 1, r, x);
  return queryh((2 * pos) + 1, l, m, x);
}

lli queryv(lli pos, lli l, lli r, lli x) {
  lli m = (l + r) / 2;
  if (lv[pos] > 0) {
    v[pos] = min(v[pos], lv[pos]);
    if (l < r) {
      lv[(2 * pos) + 1] = min(lv[(2 * pos) + 1], lv[pos]);
      lv[(2 * pos) + 2] = min(lv[(2 * pos) + 2], lv[pos]);
    }
    lv[pos] = 0;
  }
  if (l == r)
    return v[pos];
  if (x > m)
    return queryv((2 * pos) + 2, m + 1, r, x);
  return queryv((2 * pos) + 1, l, m, x);
}

void updateh(lli pos, lli l, lli r, lli ql, lli qr, lli x) {
  lli m = (l + r) / 2;
  if (lh[pos] > 0) {
    h[pos] = min(h[pos], lh[pos]);
    if (l < r) {
      lh[(2 * pos) + 1] = min(lh[(2 * pos) + 1], lh[pos]);
      lh[(2 * pos) + 2] = min(lh[(2 * pos) + 2], lh[pos]);
    }
    lh[pos] = 0;
  }
  if ((r < ql) || (l > qr))
    return;
  if ((ql <= l) && (r <= qr)) {
    h[pos] = min(h[pos], x);
    if (l < r) {
      lh[(2 * pos) + 1] = min(lh[(2 * pos) + 1], x);
      lh[(2 * pos) + 2] = min(lh[(2 * pos) + 2], x);
    }
  }
  if (l < r) {
    updateh((2 * pos) + 1, l, m, ql, qr, x);
    updateh((2 * pos) + 2, m + 1, r, ql, qr, x);
  }
}

void updatev(lli pos, lli l, lli r, lli ql, lli qr, lli x) {
  lli m = (l + r) / 2;
  if (lv[pos] > 0) {
    v[pos] = min(v[pos], lv[pos]);
    if (l < r) {
      lv[(2 * pos) + 1] = min(lv[(2 * pos) + 1], lv[pos]);
      lv[(2 * pos) + 2] = min(lv[(2 * pos) + 2], lv[pos]);
    }
    lv[pos] = 0;
  }
  if ((r < ql) || (l > qr))
    return;
  if ((ql <= l) && (r <= qr)) {
    v[pos] = min(v[pos], x);
    if (l < r) {
      lv[(2 * pos) + 1] = min(lv[(2 * pos) + 1], x);
      lv[(2 * pos) + 2] = min(lv[(2 * pos) + 2], x);
    }
  }
  if (l < r) {
    updatev((2 * pos) + 1, l, m, ql, qr, x);
    updatev((2 * pos) + 2, m + 1, r, ql, qr, x);
  }
}

int main() {
  lli q, ans, a, b;
  scanf("%lld %lld", &n, &q);
  ans = (n - 2) * (n - 2);
  for (int i = 0; i < 800001; i++)
    h[i] = v[i] = n;
  memset(lh, 0, sizeof lh);
  memset(lv, 0, sizeof lv);
  while (q--) {
    scanf("%lld %lld", &a, &b);
    if (a == 1) {
      a = queryh(0, 2, n - 1, b);
      updatev(0, 2, n - 1, 2, a - 1, b);
    } else {
      a = queryv(0, 2, n - 1, b);
      updateh(0, 2, n - 1, 2, a - 1, b);
    }
    ans -= (a - 2);
  }
  printf("%lld\\n", ans);
  return 0;
}