求看
查看原帖
求看
600441
ZhongYuLin楼主2023/10/28 20:56

ltor:从区间的左侧到右侧的最大利润

rtol:从区间的右侧到左侧的最大利润

mx:区间最大值

mn:区间最小值

#include<bits/stdc++.h>
using namespace std;

namespace IO
{
    const int I=1e6; char buf[I],stk[I],*p1,*p2;
    #define gc() (p1==p2&&(p2=(p1=buf)+cin.rdbuf()->sgetn(buf,I),p1==p2)?EOF:*p1++)
    template<typename T> inline void read(T &x)
    {
        x=0; int f=1; char ch;
        while(!isdigit(ch=gc())) if(ch=='-') f=-1;
        while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=gc();x*=f;
    }
    template<typename T,typename ...Args> inline void read(T &x, Args &...args) {read(x),read(args...);}
    template<typename T> inline void write(T x)
    {
        int top=0; if(x<0) cout.rdbuf()->sputc('-'),x=-x;
        if(!x) return cout.rdbuf()->sputc('0'),void();
        while(x) stk[++top]=x%10+48,x/=10;
        while(top) cout.rdbuf()->sputc(stk[top--]);
    }
    inline void write(const char *x) {while(*x){cout.rdbuf()->sputc(*(x++));}}
    template<typename T, typename ...Args> inline void write(T x, Args ...args) {write(x),write(args...);}
}using IO::write; using IO::read;

const int N=2e5+10,INF=0x3f3f3f3f;
struct node{
    int mx,mn,ltor,rtol;
    node(){mx=-INF;mn=INF;ltor=rtol=0;}
    node(int mx,int mn,int ltor,int rtol){this->mx=mx;this->mn=mn;this->ltor=ltor;this->rtol=rtol;}
    void merge(const node &y){
        ltor=max({ltor,y.ltor,y.mx-mn});
        rtol=max({rtol,y.rtol,mx-y.mn});
        mx=max(mx,y.mx);
        mn=max(mn,y.mn);
    }
    friend node merge(const node &x,const node &y){
        node res;
        res.merge(x);res.merge(y);
        return res;
    }
};
int head[N],to[N],nex[N],a[N];
int mx[N<<2],mn[N<<2],ltor[N<<2],rtol[N<<2],tag[N<<2];
int top[N],son[N],sz[N],dp[N],fa[N],id[N],val[N];
int n,q,tot,cnt;
void add(int u,int v){
    nex[++tot]=head[u];
    to[tot]=v;
    head[u]=tot;
}
//我保证dfs都是对的 ,请不要在意奇怪的写法 
void dfs1(int x,int f,int deep){
    fa[x]=f;dp[x]=deep;sz[x]=1;int mx=-1;
    for(int i=head[x];i;i=nex[i]){
        int y=to[i];
        if(y==f)continue;
        dfs1(y,x,deep+1);
        sz[x]+=sz[y];
        mx<sz[y]&&(mx=sz[y],son[x]=y); 
    }
}
void dfs2(int x,int topf){
    top[x]=topf;id[x]=++cnt;val[cnt]=a[x];
    if(!son[x])return;
    dfs2(son[x],topf);
    for(int i=head[x];i;i=nex[i]){
        int y=to[i];
        if(y==fa[x]||y==son[x])continue;
        dfs2(y,y);
    }
}
inline int ls(int p){return p<<1;}
inline int rs(int p){return p<<1|1;}
void push_up(int p){
    mx[p]=max(mx[ls(p)],mx[rs(p)]);
    mn[p]=min(mn[ls(p)],mn[rs(p)]);
    ltor[p]=max({ltor[ls(p)],ltor[rs(p)],mx[rs(p)]-mn[ls(p)]});
    rtol[p]=max({rtol[ls(p)],rtol[rs(p)],mx[ls(p)]-mn[rs(p)]});
}
void fix(int p,int k){
    mn[p]+=k;mx[p]+=k;tag[p]+=k;
}
void push_down(int p){
    fix(ls(p),tag[p]);fix(rs(p),tag[p]);
    tag[p]=0;
}
void build(int l=1,int r=n,int p=1){
    if(l==r){mx[p]=mn[p]=val[l];return;}
    int mid=l+r>>1;
    build(l,mid,ls(p));
    build(mid+1,r,rs(p));
    push_up(p);
}
void update(int x,int y,int k,int l=1,int r=n,int p=1){
    if(x<=l&&r<=y){fix(p,k);return;}
    int mid=l+r>>1;push_down(p);
    if(x<=mid)update(x,y,k,l,mid,ls(p));
    if(y>mid)update(x,y,k,mid+1,r,rs(p));
    push_up(p);
}
node query(int x,int y,int l=1,int r=n,int p=1){
    if(x<=l&&r<=y)return {mx[p],mn[p],ltor[p],rtol[p]};
    int mid=l+r>>1;push_down(p);
    if(y<=mid)return query(x,y,l,mid,ls(p));
    if(x>mid)return query(x,y,mid+1,r,rs(p));
    return merge(query(x,y,l,mid,ls(p)),query(x,y,mid+1,r,rs(p)));
}
void rUpdate(int x,int y,int k){
    if(top[x]^top[y]){
        if(dp[top[x]]<dp[top[y]])swap(x,y);
        update(id[top[x]],id[x],k);
        x=fa[top[x]];
    }
    if(dp[x]>dp[y])swap(x,y);
    update(id[x],id[y],k);
}
int rQuery(int x,int y){
    node l,r;
    while(top[x]^top[y]){
        if(dp[top[x]]<dp[top[y]]){
            r.merge(query(id[top[y]],id[y]));
            y=fa[top[y]];
        }else{
            l.merge(query(id[top[x]],id[x]));
            x=fa[top[x]];
        }
    }
    if(dp[x]>dp[y])l.merge(query(id[y],id[x]));
    else r.merge(query(id[x],id[y]));
    return max({r.ltor,l.rtol,r.mx-l.mn,0});
}
int main(){
    int i,j,k,u,v,w;
    freopen("P3976.in","r",stdin);
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    //请不要在意循环的写法,我确保他是正确的 
    for(read(n),i=0;++i<=n;)read(a[i]);
    for(i=0;++i<n;)read(u,v),add(u,v),add(v,u);
    dfs1(1,0,1);dfs2(1,1);build();
    for(read(q);q--;){
        read(u,v,w);
        write(rQuery(u,v),"\n");
        rUpdate(u,v,w);
    }
    return 0;
}
2023/10/28 20:56
加载中...