虽然我知道请别人帮忙调线段树是一种很恶劣的行为,尤其是考场的乱七八糟的代码,但是我真的不想再对着 170行代码发呆了,求助 dalao 。
线段树维护的值:最大值,最小值,零的个数,最小的正数,最大的负数。
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define lc (p*2)
#define rc (p*2+1)
int n,m,q;
const int N=1e5+5;
int a[N],b[N];
struct node{
int mx,mn,sum0;
int sum,sum2;
}tr[N*4],tr2[N*4];
int dp[N][25],dp2[N][25];
int c[N],d[N];
int f[25];
void push_up(int p){//
tr[p].mx=max(tr[lc].mx,tr[rc].mx);
tr[p].mn=min(tr[lc].mn,tr[rc].mn);
tr[p].sum=max(tr[lc].sum,tr[rc].sum);
tr[p].sum2=min(tr[lc].sum2,tr[rc].sum2);
tr[p].sum0=tr[lc].sum0+tr[rc].sum0;
}
void build(int p,int l,int r){//
if(l==r){
tr[p].mx=a[l];
tr[p].mn=a[l];
if(a[l]<0) tr[p].sum=a[l];
else tr[p].sum=-1e9;
if(a[l]>0) tr[p].sum2=a[l];
else tr[p].sum2=1e9;
if(a[l]==0) tr[p].sum0=1;
return ;
}
int m=l+r>>1;
build(lc,l,m);
build(rc,m+1,r);
push_up(p);
}
void push_up2(int p){//
tr2[p].mx=max(tr2[lc].mx,tr2[rc].mx);
tr2[p].mn=min(tr2[lc].mn,tr2[rc].mn);
tr2[p].sum=min(tr2[lc].sum,tr2[rc].sum);
tr2[p].sum2=max(tr2[lc].sum2,tr2[rc].sum2);
tr2[p].sum0=tr2[lc].sum0+tr2[rc].sum0;
}
void build2(int p,int l,int r){///
if(l==r){
tr2[p].mx=b[l];
tr2[p].mn=b[l];
if(b[l]<0) tr2[p].sum=b[l];
else tr2[p].sum=-1;
if(b[l]>0) tr2[p].sum2=b[l];
else tr2[p].sum2=1;
if(b[l]==0) tr2[p].sum0=1;
return ;
}
int m=l+r>>1;
build2(lc,l,m);
build2(rc,m+1,r);
push_up2(p);
}
int query(int p,int l,int r,int ql,int qr){//
if(l>=ql&&r<=qr) return tr[p].sum0;
int ans=0;
int m=l+r>>1;
if(m>=ql) ans+=query(lc,l,m,ql,qr);
if(m+1<=qr) ans+=query(rc,m+1,r,ql,qr);
return ans;
}
int query2(int p,int l,int r,int ql,int qr){//
if(l>=ql&&r<=qr) return tr2[p].sum0;
int ans=0;
int m=l+r>>1;
if(m>=ql) ans+=query2(lc,l,m,ql,qr);
if(m+1<=qr) ans+=query2(rc,m+1,r,ql,qr);
return ans;
}
int query_min(int p,int l,int r,int ql,int qr){//
if(l>=ql&&r<=qr) return tr[p].mn;
int ans=1e9;
int m=l+r>>1;
if(m>=ql) ans=min(ans,query_min(lc,l,m,ql,qr));
if(m+1<=qr) ans=min(ans,query_min(rc,m+1,r,ql,qr));
return ans;
}
int query_min2(int p,int l,int r,int ql,int qr){//
if(l>=ql&&r<=qr) return tr2[p].mn;
int ans=1e9;
int m=l+r>>1;
if(m>=ql) ans=min(ans,query_min2(lc,l,m,ql,qr));
if(m+1<=qr) ans=min(ans,query_min2(rc,m+1,r,ql,qr));
return ans;
}
int query_max(int p,int l,int r,int ql,int qr){//
if(l>=ql&&r<=qr) return tr[p].mx;
int ans=-1e9;
int m=l+r>>1;
if(m>=ql) ans=max(ans,query_max(lc,l,m,ql,qr));
if(m+1<=qr) ans=max(ans,query_max(rc,m+1,r,ql,qr));
return ans;
}
int query_max2(int p,int l,int r,int ql,int qr){//
if(l>=ql&&r<=qr) return tr2[p].mx;
int ans=-1e9;
int m=l+r>>1;
if(m>=ql) ans=max(ans,query_max2(lc,l,m,ql,qr));
if(m+1<=qr) ans=max(ans,query_max2(rc,m+1,r,ql,qr));
return ans;
}
int query_sum(int p,int l,int r,int ql,int qr){
if(l>=ql&&r<=qr) return tr[p].sum;
int ans=-1e9;
int m=l+r>>1;
if(m>=ql) ans=max(ans,query_sum(lc,l,m,ql,qr));
if(m+1<=qr) ans=max(ans,query_sum(rc,m+1,r,ql,qr));
return ans;
}
int query_2sum(int p,int l,int r,int ql,int qr){
if(l>=ql&&r<=qr) return tr[p].sum2;
int ans=1e9;
int m=l+r>>1;
if(m>=ql) ans=min(ans,query_2sum(lc,l,m,ql,qr));
if(m+1<=qr) ans=min(ans,query_2sum(rc,m+1,r,ql,qr));
return ans;
}
int query_sum2(int p,int l,int r,int ql,int qr){
if(l>=ql&&r<=qr) return tr2[p].sum;
int ans=-1;
int m=l+r>>1;
if(m>=ql) ans=min(ans,query_sum2(lc,l,m,ql,qr));
if(m+1<=qr) ans=min(ans,query_sum2(rc,m+1,r,ql,qr));
return ans;
}
int query_2sum2(int p,int l,int r,int ql,int qr){
if(l>=ql&&r<=qr) return tr2[p].sum2;
int ans=1;
int m=l+r>>1;
if(m>=ql) ans=max(ans,query_2sum2(lc,l,m,ql,qr));
if(m+1<=qr) ans=max(ans,query_2sum2(rc,m+1,r,ql,qr));
return ans;
}
int l,r,ll,rr;
signed main(){
//freopen("game.in","r",stdin);
//freopen("game.out","w",stdout);
cin>>n>>m>>q;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=m;i++) cin>>b[i];
build(1,1,n);
build2(1,1,m);
//cout<<query_2sum(1,1,n,1,6)<<' '<<query_2sum2(1,1,m,1,4)<<endl;
//cout<<query_max(1,1,n,1,4)<<endl;
while(q--){
cin>>l>>r>>ll>>rr;
if(query_min2(1,1,m,ll,rr)>=(long long)0&&query_max(1,1,n,l,r)>=(long long)0){
printf("%lld\n",query_min2(1,1,m,ll,rr)*query_max(1,1,n,l,r));
}
else if(query_max2(1,1,m,ll,rr)<=(long long)0&&query_min(1,1,n,l,r)<=(long long)0){
printf("%lld\n",query_max2(1,1,m,ll,rr)*query_min(1,1,n,l,r));
}
else if(query_min2(1,1,m,ll,rr)>=(long long)0&&query_max(1,1,n,l,r)<=(long long)0){
printf("%lld\n",query_max2(1,1,m,ll,rr)*query_max(1,1,n,l,r));
}
else if(query_max2(1,1,m,ll,rr)<=(long long)0&&query_min(1,1,n,l,r)>=(long long)0){
printf("%lld\n",query_min2(1,1,m,ll,rr)*query_min(1,1,n,l,r));
}
else{
if(query(1,1,n,l,r)>0){
printf("0\n");
}
else{
//printf("%lld %lld ",query_2sum(1,1,n,l,r),query_sum(1,1,n,l,r));
printf("%lld\n",max(query_min2(1,1,m,ll,rr)*query_2sum(1,1,n,l,r),query_max2(1,1,m,ll,rr)*query_sum(1,1,n,l,r)));
}
}
}
return 0;
}