线段树 WA 90 求助
查看原帖
线段树 WA 90 求助
726139
残阳如血楼主2024/8/30 13:55
#include <bits/stdc++.h>
#define int long long
using type_a4 = std::array<int, 4>;
const int N = 1e5 + 10, INF = 2e9;

int n, m, q, a[N], b[N];

struct SegmentTree {
  int w[N << 2], zmax[N << 2], zmin[N << 2], fmax[N << 2], fmin[N << 2];

  bool inRange(int l, int r, int L, int R) {
    return l >= L && r <= R;
  }

  bool outRange(int l, int r, int L, int R) {
    return l > R || r < L;
  }

  void pushup(int u) {
    zmax[u] = std::max(zmax[u << 1], zmax[u << 1 | 1]);
    zmin[u] = std::min(zmin[u << 1], zmin[u << 1 | 1]);
    fmax[u] = std::max(fmax[u << 1], fmax[u << 1 | 1]);
    fmin[u] = std::min(fmin[u << 1], fmin[u << 1 | 1]);
  }

  type_a4 pushup(type_a4 x, type_a4 y) {
    type_a4 res;
    res[0] = std::max(x[0], y[0]);
    res[1] = std::min(x[1], y[1]);
    res[2] = std::max(x[2], y[2]);
    res[3] = std::min(x[3], y[3]);
    return res;
  }

  void build(int *a, int u, int l, int r) {
    if (l == r) {
      w[u] = a[l];
      if (w[u] >= 0) {
        zmax[u] = zmin[u] = w[u];
        fmax[u] = -INF;
        fmin[u] = INF;
      } else {
        zmax[u] = -INF;
        zmin[u] = INF;
        fmax[u] = fmin[u] = w[u];
      }
      return ;
    }
    int mid = l + r >> 1;
    build(a, u << 1, l, mid);
    build(a, u << 1 | 1, mid + 1, r);
    pushup(u);
  }

  // 返回值依次返回 zmax, zmin, fmax, fmin
  type_a4 query(int u, int l, int r, int L, int R) {
    if (outRange(l, r, L, R)) return type_a4({-INF, INF, -INF, INF});
    if (inRange(l, r, L, R)) return type_a4({zmax[u], zmin[u], fmax[u], fmin[u]});
    int mid = l + r >> 1;
    return pushup(query(u << 1, l, mid, L, R), query(u << 1 | 1, mid + 1, r, L, R));
  }
} ta, tb;

signed main() {
  std::cin.tie(0)->sync_with_stdio(0);
  std::cin >> n >> m >> q;
  for (int i = 1; i <= n; ++i) std::cin >> a[i];
  for (int i = 1; i <= m; ++i) std::cin >> b[i];
  ta.build(a, 1, 1, n), tb.build(b, 1, 1, m);
  for (int l1, r1, l2, r2; q; --q) {
    std::cin >> l1 >> r1 >> l2 >> r2;
    auto x = ta.query(1, 1, n, l1, r1);
    auto y = tb.query(1, 1, m, l2, r2);
    if (abs(y[0]) != INF && abs(y[2]) != INF) { // 后手有正有负
      std::cout << std::max(x[1] * y[3], x[2] * y[0]) << '\n';
    } else if (abs(y[0]) != INF) { // 后手只有正数
      if (abs(x[0]) != INF) { // 先手有正数
        std::cout << x[0] * y[1] << '\n';
      } else { // 先手只有负数
        std::cout << x[2] * y[0] << '\n';
      }
    } else { // 后手只有负数
      if (abs(x[2]) != INF) { // 先手有负数
        std::cout << x[3] * y[2] << '\n';
      } else { // 先手只有正数
        std::cout << x[1] * y[3] << '\n';
      }
    }
  }
  std::cout.flush();
  return 0;
}

其中的 zmax 是正数最大值,zmin 是正数最小值,fmax 是负数最大值,fmin 是负数最小值。

2024/8/30 13:55
加载中...