求助,样例二过不了
查看原帖
求助,样例二过不了
779997
like_tis楼主2024/9/15 20:43
#include<cstdio>
#include<vector>
#include<algorithm>
#include<utility>
#define ll long long
using namespace std;
struct seg{
    int Max,Min,front,back;
    int tag;
};
int n,q,a[50005],siz[50005],fa[50005],top[50005],wc[50005],dep[50005],dfn[50005],rdfn[50005],vistime;
seg w[200005];
vector<int> g[50005];
vector<pair<int,int> > list[2];
void dfs1(int u,int f){
    siz[u]=1;
    fa[u]=f;
    dep[u]=dep[f]+1;
    for(auto v:g[u])if(v!=f){
        dfs1(v,u);
        siz[u]+=siz[v];
        if(siz[wc[u]]<siz[v]) wc[u]=v;
    }
}
void dfs2(int u,int Top){
    dfn[u]=++vistime;
    rdfn[vistime]=u;
    top[u]=Top;
    if(wc[u]!=0){
        dfs2(wc[u],Top);
        for(auto v:g[u])if(v!=fa[u]&&v!=wc[u]){
            dfs2(v,v);
        }
    }
}
void pushup(seg &z,seg x,seg y){
    z.Max=max(x.Max,y.Max);
    z.Min=min(x.Min,y.Min);
    z.front=max({x.front,y.front,y.Max-x.Min});
    z.back=max({x.back,y.back,x.Max-y.Min});
}
seg pushup(seg x,seg y){
    seg z;
    z.Max=max(x.Max,y.Max);
    z.Min=min(x.Min,y.Min);
    z.front=max({x.front,y.front,y.Max-x.Min});
    z.back=max({x.back,y.back,x.Max-y.Min});
    return z;
}
void maketag(int u,int x){
    w[u].Max+=x;
    w[u].Min+=x;
    w[u].tag+=x;
}
void pushdown(int u){
    maketag(u*2,w[u].tag);
    maketag(u*2+1,w[u].tag);
    w[u].tag=0;
}
bool inrange(int l,int r,int L,int R){
    return L<=l&&r<=R;
}
bool outofrange(int l,int r,int L,int R){
    return r<L||l>R;
}
void update(int u,int l,int r,int L,int R,int x){
    if(inrange(l,r,L,R)) maketag(u,x);
    else if(!outofrange(l,r,L,R)){
        int mid=(l+r)/2;
        pushdown(u);
        update(u*2,l,mid,L,R,x);
        update(u*2+1,mid+1,r,L,R,x);
        pushup(w[u],w[u*2],w[u*2+1]);
    }
}
seg query(int u,int l,int r,int L,int R){
    if(inrange(l,r,L,R)) return w[u];
    else{
        int mid=(l+r)/2;
        pushdown(u);
        if(R<=mid) return query(u*2,l,mid,L,R);
        if(L>mid) return query(u*2+1,mid+1,r,L,R);
        return pushup(query(u*2,l,mid,L,R),query(u*2+1,mid+1,r,L,R));
    }
}
void build(int u,int l,int r){
    if(l==r){
        w[u].Max=w[u].Min=a[rdfn[l]];
        w[u].front=w[u].back=0;
        w[u].tag=0;
        return;
    }
    int mid=(l+r)/2;
    build(u*2,l,mid);
    build(u*2+1,mid+1,r);
    pushup(w[u],w[u*2],w[u*2+1]);
}
int ask(int l,int r){
    list[0].clear();
    list[1].clear();
    int x=0;
    while(top[l]!=top[r]){
        if(dep[top[l]]<dep[top[r]]){
            swap(l,r);
            x^=1;
        }
        list[x].push_back({dfn[top[l]],dfn[l]});
        l=fa[top[l]];
    }
    if(dep[l]>dep[r]) swap(l,r);
    else x^=1;
    list[x].push_back({dfn[l],dfn[r]});
    reverse(list[1].begin(),list[1].end());
    int premax=0,ans=0;
    for(int i=0;i<=1;i++){
        for(auto j:list[i]){
            int u=j.first,v=j.second;
            seg Q=query(1,1,n,u,v);
            if(i==0) ans=max({ans,premax-Q.Min,Q.back});
            else ans=max({ans,premax-Q.Min,Q.front});
            premax=max(premax,Q.Max);
        }
    }
    return ans;
}
void Upd(int u,int v,int x){
    while(top[u]!=top[v]){
        if(dep[top[u]]<dep[top[v]]) swap(u,v);
        update(1,1,n,dfn[top[u]],dfn[u],x);
        u=fa[top[u]];
    }
    update(1,1,n,min(dfn[u],dfn[v]),max(dfn[u],dfn[v]),x);
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<n;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs1(1,0);
    dfs2(1,1);
    build(1,1,n);
    scanf("%d",&q);
    while(q--){
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        printf("%d\n",ask(u,v));
        Upd(u,v,w);
    }
    return 0;
}
2024/9/15 20:43
加载中...