线段树50分求调,悬关,谢谢
查看原帖
线段树50分求调,悬关,谢谢
649315
心灵震荡楼主2023/8/29 21:45

rt.

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

#define int long long
const int N = 100005, inf = 1e18;

struct node
{
	int l, r, mini, maxi, fmaxi, zmini;
}tree[2][N << 2];

int n, m, q, val[2][N], l1, r1, l2, r2, sum[2][N];

void pushup(int x, int id)
{
	tree[id][x].mini = min(tree[id][x << 1].mini, tree[id][x << 1 | 1].mini);
	tree[id][x].maxi = max(tree[id][x << 1].maxi, tree[id][x << 1 | 1].maxi);
	tree[id][x].fmaxi = max(tree[id][x << 1].fmaxi, tree[id][x << 1 | 1].fmaxi);
	tree[id][x].zmini = min(tree[id][x << 1].zmini, tree[id][x << 1 | 1].zmini);
}

node merge(node a, node b)
{
	node tmp;
	tmp.maxi = max(a.maxi, b.maxi);
	tmp.mini = min(a.mini, b.mini);
	tmp.fmaxi = max(a.fmaxi, b.fmaxi);
	tmp.zmini = min(a.zmini, b.zmini);
	return tmp;
}

void build(int l, int r, int x, int id)
{
	tree[id][x] = {l, r, inf, -inf, -inf, inf};
	if(l == r)
	{
		tree[id][x].mini = tree[id][x].maxi = val[id][l];
		tree[id][x].fmaxi = (val[id][l] < 0 ? val[id][l] : -inf);
		tree[id][x].zmini = (val[id][l] >= 0 ? val[id][l] : inf);
		return;
	}
	int mid = l + r >> 1;
	build(l, mid, x << 1, id);
	build(mid + 1, r, x << 1 | 1, id);
	pushup(x, id);
	return;
}

node query(int l, int r, int x, int id)
{
	if(l <= tree[id][x].l && tree[id][x].r <= r) return tree[id][x];
	int mid = tree[id][x].l + tree[id][x].r >> 1;
	node ans = {l, r, inf, -inf, -inf, inf};
	if(l <= mid) ans = merge(ans, query(l, r, x << 1, id));
	if(r > mid) ans = merge(ans, query(l, r, x << 1 | 1, id));
	return ans;
}

signed main()
{
	cin >> n >> m >> q;
	for(int i = 1; i <= n; i++) cin >> val[0][i], sum[0][i] = sum[0][i - 1] + !(val[0][i]);
	for(int i = 1; i <= m; i++) cin >> val[1][i], sum[1][i] = sum[1][i - 1] + !(val[1][i]);
	build(1, n, 1, 0);
	build(1, m, 1, 1);
	while(q--)
	{
		cin >> l1 >> r1 >> l2 >> r2;
		node nd1 = query(l1, r1, 1, 0), nd2 = query(l2, r2, 1, 1);
		int min1 = nd1.mini, min2 = nd2.mini;
		int max1 = nd1.maxi, max2 = nd2.maxi;
		int fmax1 = nd1.fmaxi, fmax2 = nd2.fmaxi;
		int zmin1 = nd1.zmini, zmin2 = nd2.zmini;
		int cnt1 = sum[0][r1] - sum[0][l1 - 1], cnt2 = sum[1][r2] - sum[1][l2 - 1];
		if(min2 >= 0) cout << max1 * min2;
		else if(max2 < 0)
		{
			if(min1 < 0) cout << min1 * (cnt2 ? 0 : fmax2);
			else cout << (cnt1 ? 0 : zmin1) * min2;
		}
		else
		{
			if(cnt1) cout << 0;
			else if(max1 < 0) cout << max1 * max2;
			else if(min1 >= 0) cout << min1 * min2;
			else cout << max(fmax1 * max2, zmin1 * min2);
		}
		cout << '\n';
	}
	return 0;
}
2023/8/29 21:45
加载中...