裸题,但是因为权在边上,所以要先把边权放到这条边的子节点上,然后进行链更新/查询的时候不能更新/查询其lca。
#include#include #include using namespace std;#define N 100001#define BN 320#define INF 2147483647int fa[N],dep[N],siz[N],son[N],Num[N],tot,top[N],a[N],bw[N],n,A[N],B[N],bs[N];int en,first[N],next[N<<1],v[N<<1],sz,NOT;void AddEdge(const int &U,const int &V){ v[++en]=V; next[en]=first[U]; first[U]=en;}void dfs(int U,int Fa,int d){ fa[U]=Fa; dep[U]=d; siz[U]=1; for(int i=first[U];i;i=next[i]) if(v[i]!=fa[U]) { dfs(v[i],U,d+1); siz[U]+=siz[v[i]]; if(siz[v[i]]>siz[son[U]]) son[U]=v[i]; }}void dfs2(int U){ if(son[U]) { top[son[U]]=top[U]; Num[son[U]]=++tot; dfs2(son[U]); } for(int i=first[U];i;i=next[i]) if(v[i]!=fa[U]&&v[i]!=son[U]) { top[v[i]]=v[i]; Num[v[i]]=++tot; dfs2(v[i]); }}int SIZ[N],TOP[N];void dfs3(int U){ for(int i=first[U];i;i=next[i]) if(v[i]!=fa[U]) { if(SIZ[TOP[U]] L&&Num[NOT] dep[V]) swap(U,V); Change_cov(Num[U],Num[V],W);}void Change_add(const int &L,const int &R,const int &W){ if(L==R&&Num[NOT]==L) return; if(Num[NOT]==L) Add(L+1,R,W); else if(Num[NOT]==R) Add(L,R-1,W); else if(Num[NOT]>L&&Num[NOT] dep[V]) swap(U,V); Change_add(Num[U],Num[V],W);}int Talk(const int &L,const int &R){ if(L==R&&Num[NOT]==L) return (-INF); if(Num[NOT]==L) return Query(L+1,R); if(Num[NOT]==R) return Query(L,R-1); if(Num[NOT]>L&&Num[NOT] dep[V]) swap(U,V); return max(res,Talk(Num[U],Num[V]));}//int cnt,LL[N],RR[N];//void dfs4(int U)//{// LL[U]=++cnt;// for(int i=first[U];i;i=next[i])// if(v[i]!=fa[U])// dfs4(v[i]);// RR[U]=cnt;//}//int Init(const int &x,const int &y)//{// if(y>=LL[x]&&y<=RR[x]) return x;// if(x>=LL[y]&&x<=RR[y]) return y;// return lca(x,y);//}int main(){// freopen("bzoj1984.in","r",stdin); scanf("%d",&n); for(int i=1;i