社区讨论

玄关球调45pts

P8818[CSP-S 2022] 策略游戏参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@mkffbl58
此快照首次捕获于
2026/01/15 20:26
上个月
此快照最后确认于
2026/01/18 12:45
上个月
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
const int ri=1e5+5;
#define pii pair<int,int>
#define mp(i,j) make_pair(i,j) 
#define int long long
int n,m,q,a[ri];
struct result{
	int maxn,minn,maxm,minm,zero;
};
struct segment_tree{
	#define ls u<<1
	#define rs u<<1|1
	struct node{
		int l,r;
		int maxn,minn,maxm,minm;
		int zero;
	}tr[ri<<2];
	void pushup(int u){
		tr[u].zero=tr[ls].zero+tr[rs].zero;
		tr[u].maxn=max(tr[ls].maxn,tr[rs].maxn);
		tr[u].minn=min(tr[ls].minn,tr[rs].minn);
	    tr[u].maxm=max(tr[ls].maxm,tr[rs].maxm);
	    tr[u].minm=min(tr[ls].minm,tr[rs].minm);
	}
	void build(int u,int l,int r){
		if(l==r){
			tr[u].l=l;
			tr[u].r=r;
			tr[u].maxn=tr[u].maxm=-0x3f3f3f3f;
			tr[u].minn=tr[u].minm=0x3f3f3f3f;
			if(a[l]<0){
				tr[u].maxm=tr[u].minm=a[l];
			}else if(a[l]==0){
				tr[u].zero=1;
			}else{
				tr[u].maxn=tr[u].minn=a[l];
			}
			return;
		}
		int mid=l+r>>1;
		build(ls,l,mid);
		build(rs,mid+1,r);
		pushup(u);
	}
	result query(int u,int l,int r,int x,int y){
		if(r<x||l>y) return (result){-0x3f3f3f3f,0x3f3f3f3f,-0x3f3f3f3f,0x3f3f3f3f,0};
		if(x<=l&&r<=y){
			return (result){tr[u].maxn,tr[u].minn,tr[u].maxm,tr[u].minm,tr[u].zero};
		}
		int mid=l+r>>1;
		result res1,res2;
		if(l<=mid) res1=query(ls,l,mid,x,y);
		if(r>mid) res2=query(rs,mid+1,r,x,y);
		return (result){max(res1.maxn,res2.maxn),
		       min(res1.minn,res2.minn),max(res1.maxm,res2.maxm),min(res1.minm,res2.minm),res1.zero+res2.zero};
	}
}t1,t2;
signed main(){
	scanf("%lld%lld%lld",&n,&m,&q);
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
	}
	t1.build(1,1,n);
	for(int i=1;i<=m;i++){
		scanf("%lld",&a[i]);
	}
	t2.build(1,1,m);
	while(q--){
		int l1,r1,l2,r2;
		scanf("%lld%lld%lld%lld",&l1,&r1,&l2,&r2);
		result k1=t1.query(1,1,n,l1,r1),k2=t2.query(1,1,m,l2,r2);
		int mx=max(k2.maxm,k2.maxn),mi=min(k2.minn,k2.minm);
		if(k2.zero){
			mx=max(0ll,mx);
			mi=min(0ll,mi);
		} 
		int g1,g2;
		if(mx>0) g1=k1.maxm*mx;
		else if(mx<0) g1=k1.minm*mx;
		else if(mx==0) g1=0;
		if(k1.zero) g1=max(g1,0ll);
		if(mi>0) g2=k1.maxn*mi;
		else if(mi<0) g2=k1.minn*mi;
		else if(mi==0) g2=0;
		if(k1.zero) g2=max(g2,0ll);
		printf("%lld\n",max(g1,g2));
	}
	return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...