破大防
查看原帖
破大防
218188
ParanoidMO楼主2022/10/30 09:52
#include<bits/stdc++.h>
using namespace std;
const long long maxn = 1e5+10;
const long long inf = 1e18+7;
struct node{
	long long amax, amin, bmax, bmin, z;
} tree1[maxn*4], tree2[maxn*4];
long long a[maxn], b[maxn];
long long n, m, q;
long long ls(long long x) {return x*2;}
long long rs(long long x) {return x*2+1;}
void push_up(long long p, long long code){
	if (code == 1){
		tree1[p].amax = max(tree1[ls(p)].amax, tree1[rs(p)].amax);	
		tree1[p].bmax = max(tree1[ls(p)].bmax, tree1[rs(p)].bmax);	
		tree1[p].amin = min(tree1[ls(p)].amin, tree1[rs(p)].amin);	
		tree1[p].bmin = min(tree1[ls(p)].bmin, tree1[rs(p)].bmin);	
		tree1[p].z = tree1[ls(p)].z || tree1[rs(p)].z;
		if (tree1[ls(p)].z == 1 || tree1[rs(p)].z == 1) tree1[p].z = 1;
		else tree1[p].z = 0;
	}
	else if (code == 2){
		tree2[p].amax = max(tree2[ls(p)].amax, tree2[rs(p)].amax);	
		tree2[p].bmax = max(tree2[ls(p)].bmax, tree2[rs(p)].bmax);	
		tree2[p].amin = min(tree2[ls(p)].amin, tree2[rs(p)].amin);	
		tree2[p].bmin = min(tree2[ls(p)].bmin, tree2[rs(p)].bmin);	
		if (tree2[ls(p)].z == 1 || tree2[rs(p)].z == 1) tree2[p].z = 1;
		else tree2[p].z = 0;
	}
}

void build(long long l, long long r, long long p, long long code){
	if (l == r){
		if (code == 1){
			if (a[l] > 0){
				tree1[p].amax = tree1[p].amin = a[l];
				tree1[p].bmax = -inf; tree1[p].bmin = 0;
				tree1[p].z = 0;
			}
			else if (a[l] < 0){
				tree1[p].bmax = tree1[p].bmin = a[l];
				tree1[p].amax = -inf; tree1[p].amin = inf;
				tree1[p].z = 0;				
			}
			else if (a[l] == 0){
				tree1[p].amin = inf; tree1[p].bmin = 0;
				tree1[p].amax = -inf; tree1[p].bmax = -inf;
				tree1[p].z = 1;					
			}
		}
		else if (code == 2){
			if (b[l] > 0){
				tree2[p].amax = tree2[p].amin = b[l];
				tree2[p].bmax = -inf; tree2[p].bmin = 0;
				tree2[p].z = 0;
			}
			else if (b[l] < 0){
				tree2[p].bmax = tree2[p].bmin = b[l];
				tree2[p].amax = -inf; tree2[p].amin = inf;
				tree2[p].z = 0;				
			}
			else if (b[l] == 0){
				tree2[p].amin = inf; tree2[p].bmin = 0;
				tree2[p].amax = -inf; tree2[p].bmax = -inf;
				tree2[p].z = 1;					
			}
		}
		return;
	}
	long long mid = (l+r)/2;
	build(l, mid, ls(p), code);
	build(mid+1, r, rs(p), code);
	push_up(p, code);
}

long long query(long long l, long long r, long long al, long long ar, long long p, long long tr_code, long long code){
	if (al <= l && r <= ar){
		if (tr_code == 1){
			if (code == 1) return tree1[p].amax;
			else if (code == 2) return tree1[p].amin;
			else if (code == 3) return tree1[p].bmax;
			else if (code == 4) return tree1[p].bmin;
			else if (code == 5) return tree1[p].z;
		}
		else if (tr_code == 2){
			if (code == 1) return tree2[p].amax;
			else if (code == 2) return tree2[p].amin;
			else if (code == 3) return tree2[p].bmax;
			else if (code == 4) return tree2[p].bmin;
			else if (code == 5) return tree2[p].z;
		}
	}
	long long mid = (l+r)/2;
	long long amax=-inf, amin=inf, bmax=-inf, bmin=0, z=0;
	if (code == 1) {
		if (mid >= al) amax = max(amax, query(l, mid, al, ar, ls(p), tr_code, code));
		if (mid < ar) amax = max(amax, query(mid+1, r, al, ar, rs(p), tr_code, code));
		return amax;
	}
	else if (code == 2) {
		if (mid >= al) amin = min(amin, query(l, mid, al, ar, ls(p), tr_code, code));
		if (mid < ar) amin = min(amin, query(mid+1, r, al, ar, rs(p), tr_code, code));
		return amin;
	}
	else if (code == 3) {
		if (mid >= al) bmax = max(bmax, query(l, mid, al, ar, ls(p), tr_code, code));
		if (mid < ar) bmax = max(bmax, query(mid+1, r, al, ar, rs(p), tr_code, code));
		return bmax;
	}
	else if (code == 4) {
		if (mid >= al) bmin = min(bmin, query(l, mid, al, ar, ls(p), tr_code, code));
		if (mid < ar) bmin = min(bmin, query(mid+1, r, al, ar, rs(p), tr_code, code));
		return bmin;
	}
	else if (code == 5){
		if (mid >= al) {
			if (query(l, mid, al, ar, ls(p), tr_code, code) == 1 || z == 1) z = 1;
			else z = 0;
		}
		if (mid < ar) {
			if (query(mid+1, r, al, ar, rs(p), tr_code, code) == 1 || z == 1) z = 1;
			else z = 0;
		}
		return z;
	}
} 
 
int main(){
	scanf("%lld%lld%lld", &n, &m, &q);
	for (long long i=1; i<=n; i++) scanf("%lld", &a[i]);
	for (long long i=1; i<=m; i++) scanf("%lld", &b[i]);
	build(1, n, 1, 1);
	build(1, m, 1, 2);
	while (q --){
		long long l1, r1, l2, r2; scanf("%lld%lld%lld%lld", &l1, &r1, &l2, &r2);
		long long amax1, amin1, bmax1, bmin1, z1, amax2, amin2, bmax2, bmin2, z2;
		amax1 = query(1, n, l1, r1, 1, 1, 1);
		amin1 = query(1, n, l1, r1, 1, 1, 2);
		bmax1 = query(1, n, l1, r1, 1, 1, 3);
		bmin1 = query(1, n, l1, r1, 1, 1, 4);
		z1 = query(1, n, l1, r1, 1, 1, 5);
		amax2 = query(1, m, l2, r2, 1, 2, 1);
		amin2 = query(1, m, l2, r2, 1, 2, 2);
		bmax2 = query(1, m, l2, r2, 1, 2, 3);
		bmin2 = query(1, m, l2, r2, 1, 2, 4);
		z2 = query(1, n, l2, r2, 1, 2, 5);
//		cout<<amax1<<" "<<amin1<<" "<<bmax1<<" "<<bmin1<<" "<<z1<<endl;
//		cout<<amax2<<" "<<amin2<<" "<<bmax2<<" "<<bmin2<<" "<<z2<<endl;
//		cout<<endl;
		if (amin1 != inf && bmax1 == -inf){ // a+
			if (amin2 != inf && bmax2 == -inf) { // b+
				printf("%lld\n", amax1*amin2);
				continue;
			}
			if (amin2 == inf && bmax2 != -inf) { // b-
				if (z1) printf("0\n");
				else printf("%lld\n", amin1*bmin2);
				continue;
			}
			if (amin2 != inf && bmax2 != -inf) { // b+-
				if (z1) printf("0\n");
				else printf("%lld\n", amin1*bmin2);
				continue;
			}
		}
		else if (amin1 == inf && bmax1 != -inf){ // a-
			if (amin2 != inf && bmax2 == -inf) { // b+
				printf("%lld\n", bmax1*amax2);
				continue;
			}
			if (amin2 == inf && bmax2 != -inf) { // b-
				if (z2) printf("0\n");
				else printf("%lld\n", bmin1*bmax2);
				continue;
			}
			if (amin2 != inf && bmax2 != -inf) { // b+-
				printf("%lld\n", bmax1*amax2);
				continue;
			}
		}
		else if (amin1 != inf && bmax1 != -inf){ // a+-
			if (amin2 != inf && bmax2 == -inf) { // b+
				if (z2) printf("0\n");
				else	printf("%lld\n", amax1*amin2);
				continue;
			}
			if (amin2 == inf && bmax2 != -inf) { // b-
				if (z2) printf("0\n");
				else printf("%lld\n", bmin1*bmax2);
				continue;
			}
			if (amin2 != inf && bmax2 != -inf) { // b+-
				if (z1) printf("0\n");
				else	printf("%lld\n", max(amin1*bmin2, bmax1*amax2));
//				cout<<"bmax2"<<bmax2<<endl;
				continue;
			}
		}
	}
	return 0;
}

洛谷 100pts

infoj 40pts

计蒜客 保龄

2022/10/30 09:52
加载中...