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

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

#define int long long
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); i++)

#define CHMIN(a, b) (a) = min((a), (b))
#define CHMAX(a, b) (a) = max((a), (b))

typedef long long ll;

int h, w, q;
int a[125252], b[125252];
const int B = 512;
int sa[125252], sb[125252];
int adda[125252 / B], addb[125252 / B];

const int INF = (1ll << 60);
const int IINF = INF >> 1;

void init() {
  REP(i, 125252) sa[i] = INF;
  REP(i, h) sa[i] = a[i];
  REP(i, (h + B - 1) / B) {
    sort(sa + i * B, sa + (i + 1) * B);
    adda[i] = 0;
  }

  REP(i, 125252) sb[i] = INF;
  REP(i, w) sb[i] = b[i];
  REP(i, (w + B - 1) / B) {
    sort(sb + i * B, sb + (i + 1) * B);
    addb[i] = 0;
  }
}

void qadd(int type, int l, int r, int v) {
  int *arr = (type == 0 ? a : b);
  int *srt = (type == 0 ? sa : sb);
  int *add = (type == 0 ? adda : addb);
  if (l % B != 0) {
    int id = l / B;
    int dd = add[id];
    add[id] = 0;
    FOR(i, id * B, (id + 1) * B) arr[i] += dd;
    while (l < r && l % B != 0) {
      arr[l] += v;
      l++;
    }
    FOR(i, id * B, (id + 1) * B) srt[i] = arr[i];
    sort(srt + id * B, srt + (id + 1) * B);
  }
  if (r % B != 0) {
    int id = r / B;
    int dd = add[id];
    add[id] = 0;
    FOR(i, id * B, (id + 1) * B) arr[i] += dd;
    while (l < r && r % B != 0) {
      r--;
      arr[r] += v;
    }
    FOR(i, id * B, (id + 1) * B) srt[i] = arr[i];
    sort(srt + id * B, srt + (id + 1) * B);
  }
  while (l < r) {
    int id = l / B;
    add[id] += v;
    l += B;
  }
}

int qmax(int type, int l, int r) {
  int *arr = (type == 0 ? a : b);
  int *srt = (type == 0 ? sa : sb);
  int *add = (type == 0 ? adda : addb);
  int ret = -INF;
  {
    int id = l / B;
    while (l < r && l % B != 0) {
      CHMAX(ret, arr[l] + add[id]);
      l++;
    }
  }
  {
    int id = r / B;
    while (l < r && r % B != 0) {
      r--;
      CHMAX(ret, arr[r] + add[id]);
    }
  }
  while (l < r) {
    int id = l / B;
    CHMAX(ret, srt[(id + 1) * B - 1] + add[id]);
    l += B;
  }
  return ret;
}

int qmin(int type, int l, int r) {
  int *arr = (type == 0 ? a : b);
  int *srt = (type == 0 ? sa : sb);
  int *add = (type == 0 ? adda : addb);
  int ret = INF;
  {
    int id = l / B;
    while (l < r && l % B != 0) {
      CHMIN(ret, arr[l] + add[id]);
      l++;
    }
  }
  {
    int id = r / B;
    while (l < r && r % B != 0) {
      r--;
      CHMIN(ret, arr[r] + add[id]);
    }
  }
  while (l < r) {
    int id = l / B;
    CHMIN(ret, srt[id * B] + add[id]);
    l += B;
  }
  return ret;
}

int qcnt(int type, int l, int r, int v) {
  int *arr = (type == 0 ? a : b);
  int *srt = (type == 0 ? sa : sb);
  int *add = (type == 0 ? adda : addb);
  int ret = 0;
  {
    int id = l / B;
    while (l < r && l % B != 0) {
      // printf("l%d r%d arrl%d\\n",l,r,arr[l]);
      ret += (int)(arr[l] + add[id] == v);
      l++;
    }
  }
  {
    int id = r / B;
    while (l < r && r % B != 0) {
      // printf("l%d r%d arrr%d\\n",l,r,arr[r]);
      r--;
      ret += (int)(arr[r] + add[id] == v);
    }
  }
  while (l < r) {
    int id = l / B;
    // x + add[id] == v
    // x == v - add[id]
    ret += upper_bound(srt + id * B, srt + (id + 1) * B, v - add[id]) -
           lower_bound(srt + id * B, srt + (id + 1) * B, v - add[id]);
    l += B;
  }
  return ret;
}

pair<ll, ll> query(int type, int l, int r, int l2, int r2) {
  int amax = qmax(0, l, r);
  int amin = qmin(0, l, r);
  int bmax = qmax(1, l2, r2);
  int bmin = qmin(1, l2, r2);
  ll val = type == 1 ? -INF : INF;
  if (type == 1) {
    CHMAX(val, (ll)amax * bmax);
    CHMAX(val, (ll)amax * bmin);
    CHMAX(val, (ll)amin * bmax);
    CHMAX(val, (ll)amin * bmin);
  } else {
    CHMIN(val, (ll)amax * bmax);
    CHMIN(val, (ll)amax * bmin);
    CHMIN(val, (ll)amin * bmax);
    CHMIN(val, (ll)amin * bmin);
  }
  if (val == 0) {
    int azero = qcnt(0, l, r, 0);
    int bzero = qcnt(1, l2, r2, 0);
    ll ret = 0;
    ret += (ll)(r - l) * (r2 - l2);
    ret -= (ll)(r - l - azero) * (r2 - l2 - bzero);
    return make_pair(val, ret);
  }
  ll ret = 0;
  if (amax == amin && bmax == bmin) {
    ret += (ll)qcnt(0, l, r, amax) * qcnt(1, l2, r2, bmax);
  } else if (amax == amin) {
    if ((ll)amax * bmax == val)
      ret += (ll)qcnt(0, l, r, amax) * qcnt(1, l2, r2, bmax);
    if ((ll)amax * bmin == val)
      ret += (ll)qcnt(0, l, r, amax) * qcnt(1, l2, r2, bmin);
  } else if (bmax == bmin) {
    if ((ll)amax * bmax == val)
      ret += (ll)qcnt(0, l, r, amax) * qcnt(1, l2, r2, bmax);
    if ((ll)amin * bmax == val)
      ret += (ll)qcnt(0, l, r, amin) * qcnt(1, l2, r2, bmax);
  } else {
    if ((ll)amax * bmax == val)
      ret += (ll)qcnt(0, l, r, amax) * qcnt(1, l2, r2, bmax);
    if ((ll)amax * bmin == val)
      ret += (ll)qcnt(0, l, r, amax) * qcnt(1, l2, r2, bmin);
    if ((ll)amin * bmax == val)
      ret += (ll)qcnt(0, l, r, amin) * qcnt(1, l2, r2, bmax);
    if ((ll)amin * bmin == val)
      ret += (ll)qcnt(0, l, r, amin) * qcnt(1, l2, r2, bmin);
  }
  return make_pair(val, ret);
}

signed main() {
  scanf("%lld%lld%lld", &h, &w, &q);
  REP(i, h) scanf("%lld", a + i);
  REP(i, w) scanf("%lld", b + i);
  init();
  while (q--) {
    int type;
    scanf("%d", &type);
    if (type <= 2) {
      int l, r, v;
      scanf("%lld%lld%lld", &l, &r, &v);
      qadd(type - 1, l - 1, r, v);
    } else {
      int l, r, l2, r2;
      scanf("%lld%lld%lld%lld", &l, &r, &l2, &r2);
      pair<ll, ll> ans = query(type - 3, l - 1, r, l2 - 1, r2);
      printf("%lld %lld\\n", ans.first, ans.second);
    }
  }
  return 0;
}


Error: TLE

Fixed submission:

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

#define int long long
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); i++)

#define CHMIN(a, b) (a) = min((a), (b))
#define CHMAX(a, b) (a) = max((a), (b))

typedef long long ll;

int h, w, q;
int a[125252], b[125252];
const int B = 125252;
int sa[125252], sb[125252];
int adda[125252 / B], addb[125252 / B];

const int INF = (1ll << 60);
const int IINF = INF >> 1;

void init() {
  REP(i, 125252) sa[i] = INF;
  REP(i, h) sa[i] = a[i];
  REP(i, (h + B - 1) / B) {
    sort(sa + i * B, sa + (i + 1) * B);
    adda[i] = 0;
  }

  REP(i, 125252) sb[i] = INF;
  REP(i, w) sb[i] = b[i];
  REP(i, (w + B - 1) / B) {
    sort(sb + i * B, sb + (i + 1) * B);
    addb[i] = 0;
  }
}

void qadd(int type, int l, int r, int v) {
  int *arr = (type == 0 ? a : b);
  int *srt = (type == 0 ? sa : sb);
  int *add = (type == 0 ? adda : addb);
  if (l % B != 0) {
    int id = l / B;
    int dd = add[id];
    add[id] = 0;
    FOR(i, id * B, (id + 1) * B) arr[i] += dd;
    while (l < r && l % B != 0) {
      arr[l] += v;
      l++;
    }
    FOR(i, id * B, (id + 1) * B) srt[i] = arr[i];
    sort(srt + id * B, srt + (id + 1) * B);
  }
  if (r % B != 0) {
    int id = r / B;
    int dd = add[id];
    add[id] = 0;
    FOR(i, id * B, (id + 1) * B) arr[i] += dd;
    while (l < r && r % B != 0) {
      r--;
      arr[r] += v;
    }
    FOR(i, id * B, (id + 1) * B) srt[i] = arr[i];
    sort(srt + id * B, srt + (id + 1) * B);
  }
  while (l < r) {
    int id = l / B;
    add[id] += v;
    l += B;
  }
}

int qmax(int type, int l, int r) {
  int *arr = (type == 0 ? a : b);
  int *srt = (type == 0 ? sa : sb);
  int *add = (type == 0 ? adda : addb);
  int ret = -INF;
  {
    int id = l / B;
    while (l < r && l % B != 0) {
      CHMAX(ret, arr[l] + add[id]);
      l++;
    }
  }
  {
    int id = r / B;
    while (l < r && r % B != 0) {
      r--;
      CHMAX(ret, arr[r] + add[id]);
    }
  }
  while (l < r) {
    int id = l / B;
    CHMAX(ret, srt[(id + 1) * B - 1] + add[id]);
    l += B;
  }
  return ret;
}

int qmin(int type, int l, int r) {
  int *arr = (type == 0 ? a : b);
  int *srt = (type == 0 ? sa : sb);
  int *add = (type == 0 ? adda : addb);
  int ret = INF;
  {
    int id = l / B;
    while (l < r && l % B != 0) {
      CHMIN(ret, arr[l] + add[id]);
      l++;
    }
  }
  {
    int id = r / B;
    while (l < r && r % B != 0) {
      r--;
      CHMIN(ret, arr[r] + add[id]);
    }
  }
  while (l < r) {
    int id = l / B;
    CHMIN(ret, srt[id * B] + add[id]);
    l += B;
  }
  return ret;
}

int qcnt(int type, int l, int r, int v) {
  int *arr = (type == 0 ? a : b);
  int *srt = (type == 0 ? sa : sb);
  int *add = (type == 0 ? adda : addb);
  int ret = 0;
  {
    int id = l / B;
    while (l < r && l % B != 0) {
      // printf("l%d r%d arrl%d\\n",l,r,arr[l]);
      ret += (int)(arr[l] + add[id] == v);
      l++;
    }
  }
  {
    int id = r / B;
    while (l < r && r % B != 0) {
      // printf("l%d r%d arrr%d\\n",l,r,arr[r]);
      r--;
      ret += (int)(arr[r] + add[id] == v);
    }
  }
  while (l < r) {
    int id = l / B;
    // x + add[id] == v
    // x == v - add[id]
    ret += upper_bound(srt + id * B, srt + (id + 1) * B, v - add[id]) -
           lower_bound(srt + id * B, srt + (id + 1) * B, v - add[id]);
    l += B;
  }
  return ret;
}

pair<ll, ll> query(int type, int l, int r, int l2, int r2) {
  int amax = qmax(0, l, r);
  int amin = qmin(0, l, r);
  int bmax = qmax(1, l2, r2);
  int bmin = qmin(1, l2, r2);
  // printf("%d %d %d %d\\n",amax,amin,bmax,bmin);
  if ((amax == 0 && amin == 0) || (bmax == 0 && bmin == 0)) {
    return make_pair(0ll, (ll)(r - l) * (r2 - l2));
  }
  ll val = type == 1 ? -INF : INF;
  if (type == 1) {
    CHMAX(val, (ll)amax * bmax);
    CHMAX(val, (ll)amax * bmin);
    CHMAX(val, (ll)amin * bmax);
    CHMAX(val, (ll)amin * bmin);
  } else {
    CHMIN(val, (ll)amax * bmax);
    CHMIN(val, (ll)amax * bmin);
    CHMIN(val, (ll)amin * bmax);
    CHMIN(val, (ll)amin * bmin);
  }
  ll ret = 0;
  if (amax == amin && bmax == bmin) {
    ret += (ll)qcnt(0, l, r, amax) * qcnt(1, l2, r2, bmax);
  } else if (amax == amin) {
    if ((ll)amax * bmax == val)
      ret += (ll)qcnt(0, l, r, amax) * qcnt(1, l2, r2, bmax);
    if ((ll)amax * bmin == val)
      ret += (ll)qcnt(0, l, r, amax) * qcnt(1, l2, r2, bmin);
  } else if (bmax == bmin) {
    if ((ll)amax * bmax == val)
      ret += (ll)qcnt(0, l, r, amax) * qcnt(1, l2, r2, bmax);
    if ((ll)amin * bmax == val)
      ret += (ll)qcnt(0, l, r, amin) * qcnt(1, l2, r2, bmax);
  } else {
    if ((ll)amax * bmax == val)
      ret += (ll)qcnt(0, l, r, amax) * qcnt(1, l2, r2, bmax);
    if ((ll)amax * bmin == val)
      ret += (ll)qcnt(0, l, r, amax) * qcnt(1, l2, r2, bmin);
    if ((ll)amin * bmax == val)
      ret += (ll)qcnt(0, l, r, amin) * qcnt(1, l2, r2, bmax);
    if ((ll)amin * bmin == val)
      ret += (ll)qcnt(0, l, r, amin) * qcnt(1, l2, r2, bmin);
  }
  return make_pair(val, ret);
}

signed main() {
  scanf("%lld%lld%lld", &h, &w, &q);
  REP(i, h) scanf("%lld", a + i);
  REP(i, w) scanf("%lld", b + i);
  init();
  while (q--) {
    int type;
    scanf("%d", &type);
    if (type <= 2) {
      int l, r, v;
      scanf("%lld%lld%lld", &l, &r, &v);
      qadd(type - 1, l - 1, r, v);
    } else {
      int l, r, l2, r2;
      scanf("%lld%lld%lld%lld", &l, &r, &l2, &r2);
      pair<ll, ll> ans = query(type - 3, l - 1, r, l2 - 1, r2);
      printf("%lld %lld\\n", ans.first, ans.second);
    }
  }
  return 0;
}