代码中变量命名习惯:
build(c,1)存的是正数
build(c,−1)存的是负数
afmax 表示 a 数组负数最大值
f 表示负 z 表示正
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=100005;
const int inf=2e9;
int n,m,q,i,j,a[N],b[N],c[N],l1,r1,l2,r2,lg[N],azmax,azmin,afmax,afmin,bzmax,bzmin,bfmax,bfmin;
bool az,af,bz,bf,an,bn;
struct st_table_max
{
int st[N][20];
void build(int s[],int symbol)
{
for(i=1;i<=n;i++)
{
if(symbol<0&&s[i]>0) s[i]=-inf;
st[i][0]=s[i];
}
for(j=1;j<=lg[n];j++)
{
for(i=1;i+(1<<j)<=n+1;i++)
{
st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);
}
}
}
int ask(int l,int r)
{
int d=lg[r-l+1];
return max(st[l][d],st[r-(1<<d)+1][d]);
}
}a_zmax,a_fmax,b_zmax,b_fmax;
struct st_table_min
{
int st[N][20];
void build(int s[],int symbol)
{
for(i=1;i<=n;i++)
{
if(symbol>0&&s[i]<0) s[i]=inf;
st[i][0]=s[i];
}
for(j=1;j<=lg[n];j++)
{
for(i=1;i+(1<<j)<=n+1;i++)
{
st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
}
}
}
int ask(int l,int r)
{
int d=lg[r-l+1];
return min(st[l][d],st[r-(1<<d)+1][d]);
}
}a_zmin,a_fmin,b_zmin,b_fmin;
void cpya()
{
for(i=1;i<=n;i++) c[i]=a[i];
}
void cpyb()
{
for(i=1;i<=n;i++) c[i]=b[i];
}
void st_init()
{
for(lg[1]=0,i=2;i<=n;i++) lg[i]=lg[(i>>1)]+1;
cpya();a_zmax.build(c,1);
cpya();a_zmin.build(c,1);
cpya();a_fmax.build(c,-1);
cpya();a_fmin.build(c,-1);
cpyb();b_zmax.build(c,1);
cpyb();b_zmin.build(c,1);
cpyb();b_fmax.build(c,-1);
cpyb();b_fmin.build(c,-1);
}
void asks()
{
az=af=an=bz=bf=bn=0;
azmax=a_zmax.ask(l1,r1);
azmin=a_zmin.ask(l1,r1);
afmax=a_fmax.ask(l1,r1);
afmin=a_fmin.ask(l1,r1);
bzmax=b_zmax.ask(l2,r2);
bzmin=b_zmin.ask(l2,r2);
bfmax=b_fmax.ask(l2,r2);
bfmin=b_fmin.ask(l2,r2);
if(afmin>0||afmax==-inf) az=1;
if(azmax<0||azmin==inf) af=1;
if(bfmin>0||bfmax==-inf) bz=1;
if(bzmax<0||bzmin==inf) bf=1;
if(!az&&!af) an=1;
if(!bz&&!bf) bn=1;
}
signed main()
{
ios::sync_with_stdio(0);cin.tie(nullptr);cout.tie(nullptr);
cin>>n>>m>>q;
for(i=1;i<=n;i++) cin>>a[i];
for(i=1;i<=m;i++) cin>>b[i];
st_init();
while(q--)
{
cin>>l1>>r1>>l2>>r2;
asks();
if(az&&bz) cout<<azmax*bzmin<<'\n';
if(az&&bf) cout<<azmin*bfmin<<'\n';
if(az&&bn) cout<<azmin*bfmin<<'\n';
if(af&&bz) cout<<afmax*bzmax<<'\n';
if(af&&bf) cout<<afmin*bfmax<<'\n';
if(af&&bn) cout<<afmax*bzmax<<'\n';
if(an&&bz) cout<<azmax*bzmin<<'\n';
if(an&&bf) cout<<afmin*bfmax<<'\n';
if(an&&bn) cout<<max(azmin*bfmin,afmax*bzmax)<<'\n';
}
return 0;
}