玄学问题求助
查看原帖
玄学问题求助
247992
_Cloud_楼主2022/11/2 23:02

我觉得代码思路应该没问题,但是本机为什么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;
}
2022/11/2 23:02
加载中...