线段树 65pts 球条(WA 均为 特殊条件:无)
查看原帖
线段树 65pts 球条(WA 均为 特殊条件:无)
757577
shz123456楼主2024/11/25 13:45
#include<cstdio>
#include<cmath>
using namespace std;

int const inf=1e9;

int const N=1e5, K=2;
int num[K][N+1];

struct numlist{
	int maxupnum, minupnum; 
	int maxlownum, minlownum; 
	
	bool upnum, lownum;
} _;

void initnum(){
	_.maxupnum = -inf, _.minupnum = inf;
	_.maxlownum = -inf, _.minlownum = inf;

	_.upnum = _.lownum = 0;
	
	return ;
}

numlist merge(numlist a, numlist b){
	numlist tmp;
	tmp.maxupnum = fmax(a.maxupnum, b.maxupnum), tmp.minupnum = fmin(a.minupnum, b.minupnum);
	tmp.maxlownum = fmax(a.maxlownum, b.maxlownum), tmp.minlownum = fmin(a.minlownum, b.minlownum);
	
	tmp.upnum = a.upnum||b.upnum, tmp.lownum = a.lownum||b.lownum;
	
	return tmp;
}

struct node{
    int left, right;
	numlist num;
} tree[K][N*4+1];

void build(int ix, int root, int left, int right){
	tree[ix][root].left = left, tree[ix][root].right = right;
	
	if(tree[ix][root].left == tree[ix][root].right){
		tree[ix][root].num = _;
		
		if(num[ix][tree[ix][root].left] >= 0){
			tree[ix][root].num.maxupnum = tree[ix][root].num.minupnum = num[ix][tree[ix][root].left];
			tree[ix][root].num.upnum = 1;
		}
		
		if(num[ix][tree[ix][root].right] <= 0){
			tree[ix][root].num.maxlownum = tree[ix][root].num.minlownum = num[ix][tree[ix][root].right]; 
			tree[ix][root].num.lownum = 1;
		}
		
		return ;
	}
	
	int mid=(tree[ix][root].left+tree[ix][root].right)/2;
	build(ix, root*2, left, mid);
	build(ix, root*2+1, mid+1, right);
	
	tree[ix][root].num = merge(tree[ix][root*2].num, tree[ix][root*2+1].num);
	
	return ;
}

numlist asks(int ix, int root, int left, int right){
	if(tree[ix][root].left>=left && tree[ix][root].right<=right) return tree[ix][root].num;
	
	numlist ans=_;
	
	int mid=(tree[ix][root].left+tree[ix][root].right)/2;
	if(left <= mid) ans = merge(ans, asks(ix, root*2, left, right));
	if(right > mid) ans = merge(ans, asks(ix, root*2+1, left, right));
	
	return ans;
}

int main(){
	initnum();
	
    int n, m, q;
    scanf("%d%d%d", &n, &m, &q);

    for(int i=1; i<=n; i++) scanf("%d", &num[0][i]);
    for(int i=1; i<=m; i++) scanf("%d", &num[1][i]);
    
    build(0, 1, 1, n);
    build(1, 1, 1, m);
    
    while(q--){
    	numlist ansnum[K];
    	for(int i=0; i<K; i++){
    		int left, right;
			scanf("%d%d", &left, &right);
			
			ansnum[i] = asks(i, 1, left, right);
		}
    	
    	long long ans;
    	if(!ansnum[0].upnum && !ansnum[1].upnum) ans = (long long)ansnum[0].minlownum*ansnum[1].maxlownum;
    	else if(!ansnum[0].lownum && !ansnum[1].lownum) ans = (long long)ansnum[0].maxupnum*ansnum[1].minupnum;
    	else if(!ansnum[0].upnum) ans = (long long)ansnum[0].maxlownum*ansnum[1].maxupnum;
    	else if(!ansnum[0].lownum) ans = (long long)ansnum[0].minupnum*ansnum[1].minlownum;
    	else if(!ansnum[1].upnum) ans = (long long)ansnum[0].minlownum*ansnum[1].maxlownum;
    	else if(!ansnum[1].lownum) ans = (long long)ansnum[0].maxupnum*ansnum[1].minupnum;
    	else ans = fmax((long long)ansnum[0].minupnum*ansnum[1].minlownum, (long long)ansnum[0].maxlownum*ansnum[1].maxupnum);
		
		printf("%lld\n", ans);
	}

    return 0;
}

2024/11/25 13:45
加载中...