求调
查看原帖
求调
1263684
Elysialr楼主2025/1/22 22:25
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define x_lc ((x<<1))
#define x_rc ((x<<1)|1)
#define x_mid ((t[x].l+t[x].r)>>1)
#define inf (1LL<<62)
#define SIZE 100001

struct node{
    ll l,r;
    ll vl,vr;
    ll data;
    ll sum;
    ll tag;
    void update(ll x){
        tag=x;
        sum=(r-l+1)*x;
        vl=max(sum,0LL);
        vr=max(sum,0LL);
        data=max(sum,0LL);
    }
};
node operator+(node x,node y){
    node res;
    res.l=x.l;
    res.r=y.r;
    res.tag=inf;
    res.sum=x.sum+y.sum;
    res.data=max(x.data,y.data);
    res.data=max(res.data,x.vr+y.vl);
    res.vl=max(x.vl,x.sum+y.vl);
    res.vr=max(y.vr,y.sum+x.vr);
    return res;
}
struct tree{
    node t[SIZE];
    void build(ll x,ll l,ll r){
        t[x].l=l;
        t[x].r=r;
        t[x].tag=inf;
        if(l==r) return;
        build(x_lc,l,x_mid);
        build(x_rc,x_mid+1,r);        
    }
    void push_down(ll x){
        if(t[x].tag!=inf){
            t[x_lc].update(t[x].tag);
            t[x_rc].update(t[x].tag);
            t[x].tag=inf;
        }
    }
    void change(ll x,ll l,ll r,ll y){
        if(t[x].l>=l&&t[x].r<=r){
            t[x].update(y);
            return;
        }
        push_down(x);
        if(x_mid>=l) change(x_lc,l,r,y);
        if(x_mid+1<=r) change(x_rc,l,r,y);
        t[x]=t[x_lc]+t[x_rc];
    }
    node query(ll x,ll l,ll r){
        if(t[x].l>=l&&t[x].r<=r) return t[x];
        push_down(x);
        if(x_mid>=l&&x_mid+1<=r) return query(x_lc,l,r)+query(x_rc,l,r);
        if(x_mid>=l) return query(x_lc,l,r);
        return query(x_rc,l,r);
    }
    void print(ll x){
        if(t[x].l==t[x].r){
            cout<<t[x].sum<<" ";
            return;
        }
        push_down(x);
        print(x_lc);
        print(x_rc);
    }
}SGT;

ll n,q,cnt;
ll w[SIZE];
ll fa[SIZE],d[SIZE];
ll sz[SIZE],son[SIZE];
ll id[SIZE],top[SIZE];
vector<ll> r[SIZE];

void dfs1(ll x){
    sz[x]=1;
    for(ll i=0;i<r[x].size();i++){
        ll y=r[x][i];
        if(y==fa[x]) continue;
        fa[y]=x;
        d[y]=d[x]+1;
        dfs1(y);
        sz[x]+=sz[y];
        if(sz[y]>sz[son[x]])
        son[x]=y;
    }
}
void dfs2(ll x,ll t){
    id[x]=++cnt;
    top[x]=t;
    SGT.change(1,id[x],id[x],w[x]);
    if(son[x]==0) return;
    dfs2(son[x],t);
    for(ll i=0;i<r[x].size();i++){
        ll y=r[x][i];
        if(y==fa[x]) continue;
        if(y==son[x]) continue;
        dfs2(y,y);
    }
}
void change(ll x,ll y,ll k){
    while(top[x]!=top[y]){
        if(d[top[x]]<d[top[y]]) swap(x,y);
        SGT.change(1,id[top[x]],id[x],k);
        x=fa[top[x]];
    }
    if(id[x]>id[y]) swap(x,y);
    SGT.change(1,id[x],id[y],k);
}
ll query(ll x,ll y){
    node left,right,tot;
    left.data=-1;
    right.data=-1;
    while(top[x]!=top[y]){
        if(d[top[x]]>d[top[y]]){
            if(left.data==-1) left=SGT.query(1,id[top[x]],id[x]);
            else left=left+SGT.query(1,id[top[x]],id[x]);
            x=fa[top[x]];
        }
        else{
            if(right.data==-1) right=SGT.query(1,id[top[y]],id[y]);
            else right=SGT.query(1,id[top[y]],id[y])+right;
            y=fa[top[y]];
        }
    }
    if(d[x]<=d[y]) tot=SGT.query(1,id[x],id[y]);
    else tot=SGT.query(1,id[y],id[x]),swap(tot.vl,tot.vr);
    if(left.data!=-1) tot=left+tot;
    if(right.data!=-1) tot=tot+right;
    return tot.data;
}

int main(){
	ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);

    cin>>n;
    SGT.build(1,1,n);
    for(ll i=1;i<=n;i++) cin>>w[i];
    for(ll i=1;i<n;i++){
        ll x,y;
        cin>>x>>y;
        r[x].push_back(y);
        r[y].push_back(x);
    }
    dfs1(1);
    dfs2(1,1);
    cin>>q;
    while(q--){
        ll op,x,y;
        cin>>op>>x>>y;
        if(op==1)cout<<query(x,y)<<endl;
        if(op==2){ll z;cin>>z;change(x,y,z);}
    }        
	return 0;
}
2025/1/22 22:25
加载中...