35pts 线段树求条
查看原帖
35pts 线段树求条
639198
Steve_xh楼主2024/10/12 18:03

具体思路是用 lrm 维护每个点上的值是由左(0)、右(1)、整个(2)传上来的

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN=200005,MAXFLOW=1ll<<30;
int n,q,a[MAXN];
struct Tree{
    int l,r,v,lrm;// l为取左区间,r为取右区间,m为左右相乘
}t[MAXN<<2|1];
inline int getmax(int xx,int yy,int &lrm){
    int x=t[xx].v,y=t[yy].v;
    if(t[xx].lrm==2||t[yy].lrm==2||(t[xx].lrm==1&&t[yy].lrm==0)){
    if((!~x)&&(!~y)){
        lrm=2;
        return -1;
    }else if((!~x)&&(~y)){
        lrm=0;
        return -1;
    }else if((~x)&&(!~y)){
        lrm=1;
        return -1;
    }

    if(x*y>x&&x*y>y){
        lrm=2;
        if(x*y>MAXFLOW)
            return -1;
        else
            return x*y;
    }else if(x>y){
        lrm=0;
        return x;
    }else{
        lrm=1;
        return y;
    }
    }else{
        if((!~x)&&(!~y)){
            lrm=2;
            return -1;
        }else if((!~x)&&(~y)){
            lrm=0;
            return -1;
        }else if((~x)&&(!~y)){
            lrm=1;
            return -1;
        }

        if(x>y){
            lrm=0;
            return x;
        }else{
            lrm=1;
            return y;
        }
    }
}
inline void pushup(int x){
    t[x].v=getmax(x<<1,x<<1|1,t[x].lrm);
}
void bt(int x,int l,int r){
    t[x].l=l,t[x].r=r;
    if(l==r){
        t[x].v=a[l];
        t[x].lrm=2;
        return ;
    }
    int mid=(l+r)>>1;
    bt(x<<1,l,mid);
    bt(x<<1|1,mid+1,r);
    pushup(x);
}
void upd(int x,int k,int w){
    if(t[x].l==t[x].r)
        return (void)(t[x].v=w);
    int mid=(t[x].l+t[x].r)>>1;
    if(k<=mid)
        upd(x<<1,k,w);
    else
        upd(x<<1|1,k,w);
    pushup(x);
}
int query(int x,int l,int r,int &lrm){
    if(l<=t[x].l&&t[x].r<=r){
        lrm=2;
        return t[x].v;
    }
    int mid=(t[x].l+t[x].r)>>1,tmp=0,ans=0,tl,tr;
    if(l<=mid){
        ans=query(x<<1,l,r,tl);
        if(tl==0||tl==2)
            lrm=0;
        else
            lrm=3;
    }
    if(mid<r){
        tmp=query(x<<1|1,l,r,tr);
        if(!ans){
            ans=tmp;
            if(tr==1||tr==2)
                lrm=1;
            else
                lrm=3;
        }else{
            if((!~ans)||(!~tmp)){
                ans=-1;
                if((!~ans)&&(!~tmp)){
                    if(tl==2&&tr==2)
                        lrm=2;
                    else if(tl==3||tr==3||(tl==1&&tr==0))
                        lrm=3;
                    else if(tl==0)
                        lrm=0;
                    else
                        lrm=1;
                }else if((!~ans)&&(~tmp)){
                    if(tl==2||tl==0)
                        lrm=0;
                    else
                        lrm=3;
                }else{
                    if(tr==2||tr==1)
                        lrm=1;
                    else
                        lrm=3;
                }
            }else{
                if(ans*tmp>ans&&ans*tmp>tmp)
                    if(tl!=3&&tr!=3&&tl!=0&&tr!=1){
                        ans*=tmp;
                        if(tl==1&&tr==0)
                            lrm=3;
                        else if(tl==2&&tr==2)
                            lrm=2;
                        else if(tl==2)
                            lrm=tr;
                        else
                            lrm=tl;
                    }
                else if(ans>tmp){
                    if(tl==2||tl==0)
                        lrm=0;
                    else
                        lrm=3;
                }else{
                    ans=tmp;
                    if(tr==2||tr==1)
                        lrm=1;
                    else
                        lrm=3;
                }
            }
        }
    }
    // cerr<<"at: "<<ans<<" "<<tmp<<'\n';
    if(ans>MAXFLOW)
        ans=-1;
    return ans;
}
signed main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    cin>>n>>q;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    bt(1,1,n);
    for(int i=1,op,x,y,lrm;i<=q;i++){
        cin>>op>>x>>y;
        if(op==1)
            upd(1,x,y);
        else{
            int k=query(1,x,y,lrm);
            if(!~k)
                cout<<"Too large\n";
            else
                cout<<max(1ll,k)<<'\n';
        }
    }
    return 0;
}
2024/10/12 18:03
加载中...