10pts 求条,有 Hack
查看原帖
10pts 求条,有 Hack
1340759
ARIS2_0楼主2024/12/30 21:29

rt,Hack 在代码末尾。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
// #define debug1(x) cerr<<#x<<"="<<x<<" "
// #define debug2(x) cerr<<#x<<"="<<x<<"\n"
const int inf=1e16,maxn=5e4+10;
int n,a[maxn],q;
vector<int>v[maxn];
//树剖第一次 DFS
int wc[maxn],size[maxn],dep[maxn],fa[maxn];
bool isw[maxn];
void dfs1(int x,int father){
    size[x]=1;
    fa[x]=father;
    int maxs=0,id=0;
    for(int y:v[x]){
        if(y!=fa[x]){
            dep[y]=dep[x]+1;
            dfs1(y,x);
            size[x]+=size[y];
            if(size[y]>maxs)maxs=size[y],id=y;
        }
    }
    wc[x]=id;
    isw[id]=1;
}
//树剖第二次 DFS
int p[maxn],d[maxn],top[maxn],tot;
void dfs2(int x){
    d[++tot]=x;
    p[x]=tot;
    top[x]=isw[x]?top[fa[x]]:x;
    if(wc[x])dfs2(wc[x]);
    for(int y:v[x]){
        if(y!=fa[x] and y!=wc[x])dfs2(y);
    }
}
struct node{int max,min,ans1,ans2,tag;}w[4*maxn];
node operator + (node a,node b){
    if(!a.min)a.min=inf;
    if(!b.min)b.min=inf;
    return node{max(a.max,b.max),min(a.min,b.min),max({a.ans1,b.ans1,a.max-b.min}),max({a.ans2,b.ans2,b.max-a.min}),0};
}
void pushup(int id){w[id]=w[id*2]+w[id*2+1];}
void build(int id,int l,int r){
    if(l==r){w[id]=node{a[d[l]],a[d[l]],0,0,0};return;}
    int mid=(l+r)/2;
    build(id*2,l,mid);
    build(id*2+1,mid+1,r);
    pushup(id);
}
void maketag(int id,int pos){
    w[id].tag+=pos;
    w[id].max+=pos;
    w[id].min+=pos;
}
void pushdown(int id){
    if(w[id].tag){
        maketag(id*2,w[id].tag);
        maketag(id*2+1,w[id].tag);
        w[id].tag=0;
    }
}
bool inr(int l,int r,int cl,int cr){return l<=r and cl<=l and r<=cr;}
node check(int id,int l,int r,int cl,int cr){
    // debug2(id);
    if(inr(l,r,cl,cr))return w[id];
    pushdown(id);
    int mid=(l+r)/2;
    node ans={0,0,0,0,0};
    if(cl<=mid)ans=ans+check(id*2,l,mid,cl,cr);
    if(cr>mid)ans=ans+check(id*2+1,mid+1,r,cl,cr);
    return ans;
}
void update(int id,int l,int r,int cl,int cr,int pos){
    if(inr(l,r,cl,cr)){maketag(id,pos);return;}
    pushdown(id);
    int mid=(l+r)/2;
    if(cl<=mid)update(id*2,l,mid,cl,cr,pos);
    if(cr>mid)update(id*2+1,mid+1,r,cl,cr,pos);
    pushup(id);
}
vector<node>res1,res2;
int check(int x,int y,int val){
    res1.clear();res2.clear();
    while(top[x]!=top[y]){
        if(dep[top[y]]>dep[top[x]]){//ans1 维护,左大右小
            res1.push_back(check(1,1,n,p[top[y]],p[y]));
            // debug2(p[top[y]]);debug2(p[y]);
            update(1,1,n,p[top[y]],p[y],val);
            y=fa[top[y]];
        }
        else{//ans2 维护,右大左小
            res2.push_back(check(1,1,n,p[top[x]],p[x]));
            // debug2(p[top[x]]);debug2(p[x]);
            update(1,1,n,p[top[x]],p[x],val);
            x=fa[top[x]];
        }
    }
    if(dep[y]>dep[x])res1.push_back(check(1,1,n,p[x],p[y])),update(1,1,n,p[x],p[y],val)/*,debug2(p[x]),debug2(p[y])*/;
    else res2.push_back(check(1,1,n,p[y],p[x])),update(1,1,n,p[y],p[x],val)/*,debug2(p[y]),debug2(p[x])*/;
    node l={0,inf,0,0,0},r={0,inf,0,0,0};
    for(node p:res2){l=l+p;}
    for(node p:res1){r=r+p;}
    // debug2(l.ans1);debug2(r.ans2);debug2(r.max);debug2(l.min);
    return max({l.ans1,r.ans2,r.max-l.min});
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=1,p,q;i<n;i++){
		cin>>p>>q;
		v[p].push_back(q);
		v[q].push_back(p);
	}
    dfs1(1,0);
    dfs2(1);
    build(1,1,n);
	cin>>q;
    while(q--){
        int posa,posb,posv;cin>>posa>>posb>>posv;
        cout<<check(posa,posb,posv)<<"\n";
    }
    /*debug2(check(1,1,n,1,2).ans2);
    debug2(check(1,1,n,1,2).max);
    debug2(check(1,1,n,1,2).min);*/
	return 0;
}
//Hack
/*
6 
2 8 6 5 11 53 
1 2 
1 3 
1 4 
3 5 
3 6
1
1 6 10

51
*/
2024/12/30 21:29
加载中...