线段树求助
查看原帖
线段树求助
520056
luoyx楼主2022/10/29 22:13

虽然我知道请别人帮忙调线段树是一种很恶劣的行为,尤其是考场的乱七八糟的代码,但是我真的不想再对着 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;
}
2022/10/29 22:13
加载中...