写的好丑~
题解:
写权值线段树合并时一定要注意一件事情:是否是在线查询或者离线查询.
离线查询意味着在树上将该点所在线段树建出来后就要马上查询,因为在之后的合并中可能会该边结构.
这么做的好处就是比较省空间.
如果要在线查询,那么就一定在合并的时候不能直接将节点信息进行累加,而是每一次都要新建节点.
// luogu-judger-enable-o2
// luogu-judger-enable-o2
#include <cstdio>
#include <algorithm>
#define N 100005
#define ls t[x].lson
#define rs t[x].rson
#define setIO(s) freopen(s".in","r",stdin) , freopen(s".out","w",stdout)
using namespace std;
int n,m,edges,cnt;
int hd[N],nex[N<<1],to[N<<1],fa[N],top[N],dep[N],siz[N],son[N];
int rt[N],tmp;
struct Node {
int lson,rson,max;
}t[N*100];
inline void addedge(int u,int v) {
nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;
}
void dfs1(int u,int ff) {
fa[u]=ff,dep[u]=dep[ff]+1,siz[u]=1;
for(int i=hd[u];i;i=nex[i]) {
int v=to[i];
if(v!=ff) {
dfs1(v,u),siz[u]+=siz[v];
if(siz[v]>siz[son[u]]) son[u]=v;
}
}
}
void dfs2(int u,int tp) {
top[u]=tp;
if(son[u]) dfs2(son[u],tp);
for(int i=hd[u];i;i=nex[i]) {
int v=to[i];
if(v==fa[u]||v==son[u]) continue;
dfs2(v,v);
}
}
int LCA(int x,int y) {
while(top[x]!=top[y]) {
dep[top[x]]>dep[top[y]]?x=fa[top[x]]:y=fa[top[y]];
}
return dep[x]<dep[y]?x:y;
}
void pushup(int x) {
t[x].max=max(t[ls].max,t[rs].max);
}
int merge(int l,int r,int x,int y) {
if(!x||!y) return x+y;
int xx=++cnt;
if(l==r) {
t[xx].max=t[y].max+t[x].max;
return xx;
}
int mid=(l+r)>>1;
if(mid>=l) t[xx].lson=merge(l,mid,t[x].lson,t[y].lson);
if(r>mid) t[xx].rson=merge(mid+1,r,t[x].rson,t[y].rson);
pushup(xx);
return xx;
}
void update(int l,int r,int &x,int p,int z) {
if(!x)x=++cnt;
if(l==r) {
t[x].max+=z;
return;
}
int mid=(l+r)>>1;
if(p<=mid) update(l,mid,ls,p,z);
else update(mid+1,r,rs,p,z);
pushup(x);
}
void dfs(int u,int ff) {
for(int i=hd[u];i;i=nex[i]) {
int v=to[i];
if(v!=ff) dfs(v,u),rt[u]=merge(1,100000,rt[v],rt[u]);
}
}
int find(int l,int r,int x) {
if(l==r) return l;
int mid=(l+r)>>1;
if(t[ls].max==tmp) return find(l,mid,ls);
else return find(mid+1,r,rs);
}
int main() {
int i,j;
// setIO("input");
scanf("%d%d",&n,&m);
for(i=1;i<n;++i) {
int a,b;
scanf("%d%d",&a,&b),addedge(a,b),addedge(b,a);
}
dfs1(1,0),dfs2(1,1);
for(i=1;i<=m;++i) {
int x,y,z,lca;
scanf("%d%d%d",&x,&y,&z);
lca=LCA(x,y);
update(1,100000,rt[x],z,1), update(1,100000,rt[y],z,1),update(1,100000,rt[lca],z,-1);
if(fa[lca]) update(1,100000,rt[fa[lca]],z,-1);
}
dfs(1,0);
for(i=1;i<=n;++i) {
tmp=t[rt[i]].max;
if(!tmp) printf("%d\n",tmp);
else {
printf("%d\n",find(1,100000,rt[i]));
}
}
return 0;
}