玄关,0pts求调
查看原帖
玄关,0pts求调
632409
Dream_not_found楼主2024/10/16 21:35

纯用线段树敲的,马蜂丑陋,还请海涵。

本人建了两个线段树,分别存aa数组和bb数组正数最大最小值和负数最大最小值,然后分别去求区间内所需的最值。


code:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<deque>
#include<map>
#include<sstream>
#include<set>
#define ls p>>1
#define rs (p>>1)+1
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e5+10,M=1e5+10;
const double PI=acos(-1.0);
const double eps=1e-6;
const ll mod=1e9+7;
const int INF=0x3f3f3f3f;

inline int read(){
    int f=1,x=0; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=getchar();
    return f*x;
}

int n,m,q;
int a[N],b[N];
struct node{
	int max_zhenga=-INF,max_zhengb=-INF;
	int min_zhenga=INF,min_zhengb=INF;
	int max_fua=-INF,max_fub=-INF;
	int min_fua=INF,min_fub=INF;
}t1[2*N],t2[2*N];
void build_a(int l,int r,int p){
	if(l==r){
		if(a[l]>=0){
			t1[p].max_zhenga=a[l];
			t1[p].min_zhenga=a[l];
		}
		else{
			t1[p].max_fua=a[l];
			t1[p].min_fua=a[l];
		}
		return;
	}
	int mid=(l+r)>>1;
	build_a(l,mid,ls);
	build_a(mid+1,r,rs);
	t1[p].max_zhenga=max(t1[ls].max_zhenga,t1[rs].max_zhenga);
	t1[p].min_zhenga=min(t1[ls].min_zhenga,t1[rs].min_zhenga);
	t1[p].max_fua=max(t1[ls].max_fua,t1[rs].max_fua);
	t1[p].min_fua=min(t1[ls].min_fua,t1[rs].min_fua);
}
void build_b(int l,int r,int p){
	if(l==r){
		if(b[l]>=0){
			t2[p].max_zhengb=b[l];
			t2[p].min_zhengb=b[l];
		}
		else{
			t2[p].max_fub=b[l];
			t2[p].min_fub=b[l];
		}
		return;
	}
	int mid=(l+r)>>1;
	build_b(l,mid,ls);
	build_b(mid+1,r,rs);
	t2[p].max_zhengb=max(t2[ls].max_zhengb,t2[rs].max_zhengb);
	t2[p].min_zhengb=min(t2[ls].min_zhengb,t2[rs].min_zhengb);
	t2[p].max_fub=max(t2[ls].max_fub,t2[rs].max_fub);
	t2[p].min_fub=min(t2[ls].min_fub,t2[rs].min_fub);
}
int query_max_a1(int l,int r,int L,int R,int p){
	if(L<=l&&r<=R)return t1[p].max_zhenga;
	int mid=(l+r)>>1;
	int sum=-INF;
	if(L<=mid)sum=query_max_a1(l,mid,L,R,ls);
	if(R>mid)sum=max(query_max_a1(mid+1,r,L,R,ls),sum);
	return sum;
}
int query_min_a1(int l,int r,int L,int R,int p){
	if(L<=l&&r<=R)return t1[p].min_zhenga;
	int mid=(l+r)>>1;
	int sum=INF;
	if(L<=mid)sum=query_min_a1(l,mid,L,R,ls);
	if(R>mid)sum=min(query_min_a1(mid+1,r,L,R,ls),sum);
	return sum;
}
int query_max_a2(int l,int r,int L,int R,int p){
	if(L<=l&&r<=R)return t1[p].max_fua;
	int mid=(l+r)>>1;
	int sum=-INF;
	if(L<=mid)sum=query_max_a2(l,mid,L,R,ls);
	if(R>mid)sum=max(query_max_a2(mid+1,r,L,R,ls),sum);
	return sum;
}
int query_min_a2(int l,int r,int L,int R,int p){
	if(L<=l&&r<=R)return t1[p].min_fua;
	int mid=(l+r)>>1;
	int sum=INF;
	if(L<=mid)sum=query_min_a2(l,mid,L,R,ls);
	if(R>mid)sum=min(query_min_a2(mid+1,r,L,R,ls),sum);
	return sum;
}
int query_max_b1(int l,int r,int L,int R,int p){
	if(L<=l&&r<=R)return t2[p].max_zhengb;
	int mid=(l+r)>>1;
	int sum=-INF;
	if(L<=mid)sum=query_max_b1(l,mid,L,R,ls);
	if(R>mid)sum=max(query_max_b1(mid+1,r,L,R,ls),sum);
	return sum;
}
int query_min_b1(int l,int r,int L,int R,int p){
	if(L<=l&&r<=R)return t2[p].min_zhengb;
	int mid=(l+r)>>1;
	int sum=INF;
	if(L<=mid)sum=query_min_b1(l,mid,L,R,ls);
	if(R>mid)sum=min(query_min_b1(mid+1,r,L,R,ls),sum);
	return sum;
}
int query_max_b2(int l,int r,int L,int R,int p){
	if(L<=l&&r<=R)return t2[p].max_fub;
	int mid=(l+r)>>1;
	int sum=-INF;
	if(L<=mid)sum=query_max_b2(l,mid,L,R,ls);
	if(R>mid)sum=max(query_max_b2(mid+1,r,L,R,ls),sum);
	return sum;
}
int query_min_b2(int l,int r,int L,int R,int p){
	if(L<=l&&r<=R)return t2[p].min_fub;
	int mid=(l+r)>>1;
	int sum=INF;
	if(L<=mid)sum=query_min_b2(l,mid,L,R,ls);
	if(R>mid)sum=min(query_min_b2(mid+1,r,L,R,ls),sum);
	return sum;
}
bool fa1,fa2,fb1,fb2;
int l1,l2,r1,r2;
ll ans;
int main(){
	scanf("%d%d%d",&n,&m,&q);
	for(int i=1;i<=n;i++)
		scanf("%d",a+i);
	for(int i=1;i<=m;i++)
		scanf("%d",b+i);
	build_a(1,n,1);
	build_b(1,m,1);
	while(q--){
		fa1=fa2=fb1=fb2=0;
		scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
		for(int i=l1;i<=r1;i++){
			if(a[i]>=0)fa1=1;
			else fa2=1;
		}
		for(int i=l2;i<=r2;i++){
			if(a[i]>=0)fb1=1;
			else fb2=1;
		}
//		printf("%d %d %d %d\n",query_max_a1(1,n,l1,r1,1),query_min_a1(1,n,l1,r1,1),query_max_a2(1,n,l1,r1,1),query_min_a2(1,n,l1,r1,1));
//		printf("%d %d %d %d\n",query_max_b1(1,n,l2,r2,1),query_min_b1(1,n,l2,r2,1),query_max_b2(1,n,l2,r2,1),query_min_b2(1,n,l2,r2,1));
		if(fb1&&fb2){
			if(fa1&&!fa2)
				ans=query_min_a1(1,n,l1,r1,1)*query_min_b2(1,n,l2,r2,1);
			else if(!fa1&&fa2)
				ans=query_max_a2(1,n,l1,r1,1)*query_max_b1(1,n,l2,r2,1);
			else ans=max(query_min_a1(1,n,l1,r1,1)*query_min_b2(1,n,l2,r2,1),query_max_a2(1,n,l1,r1,1)*query_max_b1(1,n,l2,r2,1));
		}
		else if(fb1&&!fb2){
			if(fa1)	ans=query_max_a1(1,n,l1,r1,1)*query_max_b1(1,n,l2,r2,1);
			else ans=query_max_a2(1,n,l1,r1,1)*query_max_b1(1,n,l2,r2,1);
		}
		else{
			if(fa2) ans=query_min_a2(1,n,l1,r1,1)*query_max_b2(1,n,l2,r2,1);
			else ans=query_min_a1(1,n,l1,r1,1)*query_max_b2(1,n,l2,r2,1);
		}
		printf("%lld\n",ans);
	}
	return 0;
}

写的很长,主要是写了8个单点求值
2024/10/16 21:35
加载中...