求助
查看原帖
求助
785181
sunjishuo楼主2023/10/13 19:59
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;

typedef long long LL;
#define INF 2e15
const int N = 1E5 + 10;

int n, m, q;

struct point
{
	int l, r;
	LL mmax = 0, mmin = 0;
}treey[N * 4], treex[N * 4], treex_min_pos[N * 4], treex_max_neg[N * 4], zerox[N * 4], zeroy[N * 4];

void build(int u, int l, int r, point* tr)
{
	tr[u].l = l; tr[u].r = r;
	if (l == r) 
	{
//		cout << u << ' ' << l << endl;
		return;
	}
	int mid = l + r >> 1;
	build (u << 1, l, mid, tr);
	build (u << 1 | 1, mid + 1, r, tr); 	
}

void pushup(int u, point * tr)
{
	tr[u].mmax = max(tr[u << 1].mmax, tr[u << 1 | 1].mmax);
	tr[u].mmin = min(tr[u << 1].mmin, tr[u << 1 | 1].mmin);
}

void modify(int u, int x, LL v, point *tr)
{
	if (tr[u].l == x && tr[u].r == x) 
	{
		tr[u].mmax = v;
		tr[u].mmin = v;
		return;
	}
	else 
	{
		int mid = tr[u].l + tr[u].r >> 1;
		if (x <= mid) modify(u << 1, x, v, tr);
		else if (x > mid) modify(u << 1 | 1, x, v, tr);
		pushup(u, tr);
	}
}

LL query_max(int u, int l, int r, point* tr)
{
	if (tr[u].l >= l && tr[u].r <= r) return tr[u].mmax;
	LL v = -INF;
	int mid = tr[u].l + tr[u].r >> 1;
	if (l <= mid) v = query_max(u << 1, l, mid, tr);
	if (r > mid) v = max(v, query_max(u << 1 | 1, mid + 1, r, tr));
	return v;
}

LL query_min(int u, int l, int r, point* tr)
{
	if (tr[u].l >= l && tr[u].r <= r) {

	   // cout << tr[u].mmin << endl;
	    return tr[u].mmin;
	}
	LL v = INF;
	int mid = tr[u].l + tr[u].r >> 1;
	if (l <= mid) v = query_min(u << 1, l, mid, tr);
	if (r > mid) v = min(v, query_min(u << 1 | 1, mid + 1, r, tr));
	return v;
}
int main()
{
	cin >> n >> m >> q;
	build (1, 1, m, treey);
	build (1, 1, n, treex);
	build (1, 1, n, treex_min_pos);
	build (1, 1, n, treex_max_neg);
	build (1, 1, n, zerox);
	build (1, 1, m, zeroy);
	for (int i = 1; i <= n; i ++ ) modify(1, i, INF, treex_min_pos);
	for (int i = 1; i <= n; i ++ ) modify(1, i, -INF, treex_max_neg);
	
	for (int i = 1; i <= n; i ++ )
	{
		LL t; scanf("%lld", &t); //////////exp
		modify(1, i, t, treex);
		if (t >= 0) modify(1, i, t, treex_min_pos);
		else modify(1, i, t, treex_max_neg);
		if (t == 0) modify(1, i, 1, zerox);
	}
	
	for (int i = 1; i <= m; i ++ )
	{
		LL t; scanf("%lld", &t);
		modify(1, i, t, treey);
		if (t == 0) modify(1, i, 1, zeroy);
	}
	
	for (int i = 1; i <= q; i ++ )
	{
		int l1, r1, l2, r2; bool zx, zy; LL ans, ans1 = -INF, ans2 = -INF, ans3 = -INF, ans4 = -INF;
		scanf("%d%d%d%d", &l1, &r1, &l2, & r2);
		LL y_min = query_min(1, l2, r2, treey);
		LL y_max = query_max(1, l2, r2, treey);
		LL x_max = query_max(1, l1, r1, treex);
		LL x_min = query_min(1, l1, r1, treex);
		LL x_min_pos = query_min(1, l1, r1, treex_min_pos);
		LL x_max_neg = query_max(1, l1, r1, treex_max_neg);
		if (query_max(1, l1, r1, zerox)) zx = true;
		if (query_max(1, l2, r2, zeroy)) zy = true;
		if (y_min >= 0)
		{
			ans1 = y_min * x_max;
			if (x_max == 0 && !zx) ans1 = -INF;
		}
		else if (y_min < 0)
		{
			ans2 = y_min * x_min_pos;
			if (x_min_pos == INF && !zx) ans2 = -INF;
		}
		
		if (y_max >= 0)
		{
			ans3 = y_max * x_max_neg;
			if (x_max_neg == -INF && !zx) ans3 = -INF;
 		}
		else if (y_max < 0)
		{
			ans4 = y_max * x_min;
			if (x_min == 0 && !zx) ans4 = -INF;
		}
		LL aa, bb;
		aa = max(ans1, ans2);
		bb = max(ans3, ans4);
		ans = max(aa, bb);
		printf("%lld\n", ans);
 	}
	return 0;
}
2023/10/13 19:59
加载中...