树剖板子求调,已过所有样例和题解的 hack 数据
查看原帖
树剖板子求调,已过所有样例和题解的 hack 数据
482660
konyakest楼主2023/7/16 07:14
#ifdef DEBUG
#define GNU_DEBUG
#define _GLIBCXX_DEBUG 1
#define _GLIBCXX_DEBUG_PEDANTIC 1
#define _GLIBCXX_SANITIZE_VECTOR 1
#endif

#include<bits/stdc++.h>
#include<bits/extc++.h>
#define F(i,j,k) for(auto i=j;i<=(decltype(i))k;i++)
#define exec(...) [&](){__VA_ARGS__}()
#define lambda [&]
#define endl '\n'
#define view(x) begin(x),end(x)
#define pb push_back
#define x first
#define y second
#define os ostream
using namespace std;
using namespace __gnu_pbds;
template<typename T>void ckmax(T& a,T b){a=max(a,b);}
template<typename T>void ckmin(T& a,T b){a=min(a,b);}

#ifdef DEBUG
template<typename T1,typename T2>os& operator<<(os& out,pair<T1,T2> x){return out<<tuple(x);}
template<typename T,typename=decltype(T().begin()),typename=enable_if_t<!is_same_v<decay_t<T>,string>>>os& operator<<(os& out,T x){return out<<"{",exec(auto n=0u;for(auto i:x) out<<i<<(++n==x.size()?"":",");),out<<"}";}
template<typename...T>os& operator<<(os& out,tuple<T...> x){return apply(lambda(T... xx){auto n=0u;out<<"{",((out<<xx<<(++n==sizeof...(T)?"":",")),...),out<<"}";},x),out;}
#define debug(...) cerr<<"#"<<__LINE__<<": "<<#__VA_ARGS__<<" = "<<std::make_tuple(__VA_ARGS__)<<endl
#else
#define debug(...) (void)0
#endif
#define nodebug(...) (void)0

const int maxn=1e5+5;
#define int long long

int n,q,op,x,y,mson[maxn],id[maxn],siz[maxn];
int top[maxn],cnt,fa[maxn],dep[maxn],val[maxn],z;
vector<int> v[maxn];

struct Node{
    int sum,lmx,rmx,mx; 
}w[maxn];

Node merge(const Node& n1,const Node& n2){
    return {
        n1.sum+n2.sum,
        max(n1.lmx,n1.sum+n2.lmx),
        max(n2.rmx,n2.sum+n1.rmx),
        max({n1.rmx+n2.lmx,n1.mx,n2.mx})
    };
}

void dfs1(int u,int f){
    siz[u]=1;
    fa[u]=f;
    dep[u]=dep[f]+1;
    for(auto i:v[u]) if(i!=f){
        dfs1(i,u);
        siz[u]+=siz[i];
        if(siz[mson[u]]<siz[i]) mson[u]=i;
    }
}

void dfs2(int u,int tp){
    cnt++;
    id[u]=cnt,top[u]=tp;
    w[cnt]={val[u],max(val[u],0ll),max(val[u],0ll),max(val[u],0ll)};
    // debug(val[u],cnt,w[cnt]);
    // debug(u,cnt,w[cnt].mx,w[cnt].lmx,w[cnt].rmx);
    // debug(u,id[u],top[u]);
    if(mson[u]) dfs2(mson[u],tp);
    for(auto i:v[u]) if(i!=fa[u]&&i!=mson[u]) dfs2(i,i);
}



// os& operator<<(os& out,Node n){
//     return out<<tuple(n.sum,n.lmx,n.rmx,n.mx);
// }

#define ls node*2
#define rs node*2+1
#define mid (l+r)/2
#define pkgl l,mid,ls
#define pkgr mid+1,r,rs

struct Segment{
    Node t[maxn*4];
    int tag[maxn*4];
    bool vis[maxn*4];
    Segment(){
        memset(t,0,sizeof t);
        memset(tag,0,sizeof tag);
        memset(vis,0,sizeof vis);
        // memset(tag,-0x3f,sizeof tag);
        // fill(view(tag),-1234567890);
    }
    void push_up(int node){t[node]=merge(t[ls],t[rs]);}
    void build(int l,int r,int node){
        if(l==r) return t[node]=w[l],(void)0;
        build(pkgl),build(pkgr);
        push_up(node);
        // debug(l,r,t[node].mx);
    }
    void updtag(int l,int r,int node,int want){
        // if(want==-1234567890) return;
        t[node].sum=(r-l+1)*want;
        t[node].lmx=t[node].rmx=t[node].mx=max(t[node].sum,0ll);
        tag[node]=want;
        vis[node]=1;
    }
    void push_down(int l,int r,int node){
        if(vis[node]){
            updtag(pkgl,tag[node]);
            updtag(pkgr,tag[node]);
            // tag[node]=-1234567890;
            vis[node]=0;
        }
    }
    void update(int l,int r,int node,int x,int y,int want){
        if(x<=l&&r<=y) return updtag(l,r,node,want),vis[node]=1,(void)0;
        push_down(l,r,node);
        if(mid>=x) update(pkgl,x,y,want);
        else update(pkgr,x,y,want);
        push_up(node);
    }
    Node query(int l,int r,int node,int x,int y){
        // debug(l,r,node,x,y,t[node].mx);
        if(x<=l&&r<=y) return t[node];
        push_down(l,r,node);
        if(mid>=x){
            if(mid<y) return merge(query(pkgl,x,y),query(pkgr,x,y));
            else return query(pkgl,x,y);
        }
        else return query(pkgr,x,y);
    }
}t;

void updLine(int x,int y,int c){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]) swap(x,y);
        t.update(1,n,1,id[top[x]],id[x],c);
        x=fa[top[x]];
    }
    if(dep[x]<dep[y]) swap(x,y);
    t.update(1,n,1,id[y],id[x],c);
}

int qryLine(int x,int y){
    // debug(x,y,top[x],top[y],id[top[x]],id[top[y]]);
    Node ans1={0,0,0,0},ans2={0,0,0,0};
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]]){
            ans2=merge(t.query(1,n,1,id[top[y]],id[y]),ans2);
            // debug(t.query(1,n,1,id[top[y]],id[top[y]]).mx);
            // debug(top[y],y,ans1.mx,rev(t.query(1,n,1,id[top[y]],id[y])).mx);
            y=fa[top[y]];
        }
        else{
            ans1=merge(t.query(1,n,1,id[top[x]],id[x]),ans1);
            // debug(top[x],x,ans2.mx);
            x=fa[top[x]];
        }
    }
    // debug(x,y,ans1,ans2,dep[x],dep[y]);
    // if(x==y) return merge(ans1,ans2).mx;
    if(dep[x]>dep[y]) ans1=merge(t.query(1,n,1,id[y],id[x]),ans1);
    else ans2=merge(t.query(1,n,1,id[x],id[y]),ans2);
    swap(ans1.lmx,ans2.rmx);
    return merge(ans1,ans2).mx;
}

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n;
    F(i,1,n) cin>>val[i];
    F(i,1,n-1) cin>>x>>y,v[x].pb(y),v[y].pb(x);
    cin>>q;
    dfs1(1,1),dfs2(1,1);
    t.build(1,n,1);
    F(i,1,q){
        cin>>op>>x>>y;
        if(op==1) cout<<qryLine(x,y)<<endl;
        else cin>>z,updLine(x,y,z);
    }
    return 0;
}
2023/7/16 07:14
加载中...