我觉得代码思路应该没问题,但是本机为什么M开到1e5连运行都运行不起来,但我觉得空间应该够的呀,就1e6左右……
还有,本机的大样例3在M开到1e4的时候跑的很快,交洛谷M改到1e5后跑的就特别慢……,请问是为什么?
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 1e5 + 5;
const int M = 1e5 + 5;//M开到1e5本地无法运行,请问是为什么
const int INF = 1e9 + 5;
int a[N], b[N], now[N];
int n, m, Q;
struct Tree {
int minn[N << 2], maxn[N << 2], zero[N << 2];
inline int ls(int p) { return p << 1; }
inline int rs(int p) { return p << 1 | 1; }
inline void push_up(int p) {
minn[p] = min(minn[ls(p)], minn[rs(p)]);
maxn[p] = max(maxn[ls(p)], maxn[rs(p)]);
zero[p] = zero[ls(p)] + zero[rs(p)];
}
inline void build(int l, int r, int p, int flag) {
minn[p] = INF, maxn[p] = -INF; zero[p] = 0;
if (l == r) {
if (flag * now[l] >= 0) maxn[p] = minn[p] = now[l];
else maxn[p] = -INF, minn[p] = INF;
if (now[l] == 0) zero[p] = 1;
return;
}
int mid = l + r >> 1;
build(l, mid, ls(p), flag); build(mid + 1, r, rs(p), flag);
push_up(p);
}
inline int QueryMin(int L, int R, int l, int r, int p) {
if (L <= l && r <= R) return minn[p];
int mid = l + r >> 1, res = INF;
if (L <= mid) res = min(res, QueryMin(L, R, l, mid, ls(p)));
if (mid < R) res = min(res, QueryMin(L, R, mid + 1, r, rs(p)));
return res;
}
inline int QueryMax(int L, int R, int l, int r, int p) {
if (L <= l && r <= R) return maxn[p];
int mid = l + r >> 1, res = -INF;
if (L <= mid) res = max(res, QueryMax(L, R, l, mid, ls(p)));
if (mid < R) res = max(res, QueryMax(L, R, mid + 1, r, rs(p)));
return res;
}
inline int QueryZero(int L, int R, int l, int r, int p) {
if (L <= l && r <= R) return zero[p];
int mid = l + r >> 1, res = 0;
if (L <= mid) res += QueryZero(L, R, l, mid, ls(p));
if (mid < R) res += QueryZero(L, R, mid + 1, r, rs(p));
return res;
}
} A, A1, A2, B; //1 : +, 2 : -
void init() {
for (int i = 1; i <= n; i++) now[i] = a[i];
A.build(1, n, 1, 0);
// for (int i = 1; i <= n; i++) printf("%d ", A.QueryMin(1, i, 1, n, 1)); puts("");
A1.build(1, n, 1, 1); A2.build(1, n, 1, -1);
for (int i = 1; i <= m; i++) now[i] = b[i];
B.build(1, m, 1, 0);//for (int i = 1; i <= m; i++) printf("%d ", B.QueryMin(1, i, 1, m, 1)); puts("");
// B1.build(1, m, 1, 1); B2.build(1, m, 1, -1);
}
int search(Tree tr, int L, int R, int l, int r) {
int zh = 0, fu = 0;
if (tr.QueryMax(L, R, l, r, 1) > 0) zh = 1;
if (tr.QueryMin(L, R, l, r, 1) < 0) fu = 1;
if (zh && !fu) return 1;
if (!zh && fu) return -1;
if (zh && fu) return 2;
if (!zh && !fu) return 0;
return 0;
}
int main() {
// freopen("game.in","r",stdin);
// freopen("game.out","w",stdout);
scanf("%d %d %d", &n, &m, &Q);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
for (int i = 1; i <= m; i++) scanf("%d", &b[i]);
init();
while (Q--) {
int l1, r1, l2, r2;
scanf("%d %d %d %d", &l1, &r1, &l2, &r2);
int x = search(A, l1, r1, 1, n), y = search(B, l2, r2, 1, m);
// printf("x=%d y=%d\n", x, y);
long long ans = 0;
if (x == 1) {
if (y == 1) ans = 1ll* A.QueryMax(l1, r1, 1, n, 1) * B.QueryMin(l2, r2, 1, m, 1);
else if (y == -1) ans = 1ll * A.QueryMin(l1, r1, 1, n, 1) * B.QueryMin(l2, r2, 1, m, 1);
else if (y == 2) ans = 1ll * A.QueryMin(l1, r1, 1, n, 1) * B.QueryMin(l2, r2, 1, m, 1);
}
else if (x == -1) {
if (y == 1) ans = 1ll * A.QueryMax(l1, r1, 1, n, 1) * B.QueryMax(l2, r2, 1, m, 1);
else if (y == -1) ans = 1ll * A.QueryMin(l1, r1, 1, n, 1) * B.QueryMax(l2, r2, 1, m, 1);
else if (y == 2) ans = 1ll * A.QueryMax(l1, r1, 1, n, 1) * B.QueryMax(l2, r2, 1, m, 1);
}
else if (x == 2) {
if (y == 1) ans = 1ll * A.QueryMax(l1, r1, 1, n, 1) * B.QueryMin(l2, r2, 1, m, 1);
else if (y == -1) ans = 1ll * A.QueryMin(l1, r1, 1, n, 1) * B.QueryMax(l2, r2, 1, m, 1);
else if (y == 2) ans = max(1ll * A2.QueryMax(l1, r1, 1, n, 1) * B.QueryMax(l2, r2, 1, m, 1),
1ll * A1.QueryMin(l1, r1, 1, n, 1) * B.QueryMin(l2, r2, 1, m, 1));
}
int zero1 = A.QueryZero(l1, r1, 1, n, 1), zero2 = B.QueryZero(l2, r2, 1, n, 1);
// printf("%lld\n", ans);
if (ans < 0 && zero1 > 0) ans = 0;
if (ans > 0 && zero2 > 0) ans = 0;
printf("%lld\n", ans);
}
return 0;
}