题目:
题意:
在一个村子中,有些房子互相连通,并使得整个村子成为了一个树形结构
现在会有
m
m
m次发放救济粮的机会,
(
u
,
v
,
z
)
(u,v,z)
(u,v,z)表示由
u
u
u到
v
v
v一整条路径上都加上一次
z
z
z种的粮食
问我们每个房子存放数量最多的粮食是哪个品种
分析:
我们可以通过差分来表示一段房子的增值,在
u
,
v
u,v
u,v打上
+
1
+1
+1,在它们的
L
C
A
LCA
LCA和
L
C
A
LCA
LCA的父亲打上
−
1
-1
−1
接着我们用线段树合并进行
l
o
g
log
log的求解
代码:
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#define LL long long
#define LZX WCIMU
using namespace std;
inline LL read() {
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
int n,m,top,ls[200005],ans[100005];
struct mona {int next,to;} s[200005];
struct joker {int next,to,op;};
void Insert(int x,int y) {s[++top]=(mona){ls[x],y},ls[x]=top; }
struct SeqTree
{
int cnt,lson[4000005],rson[4000005],Max[4000005],id[4000005],rt[100005],rab[4000005],tot,top,ls[100005]; joker s[400005];
void Insert(int x,int y,int op) { s[++top]=(joker) {ls[x],y,op},ls[x]=top; }
int New() {if(tot) return rab[tot--]; return ++cnt; }
void Throw(int x) {rab[++top]=x,lson[x]=rson[x]=Max[x]=id[x]=0; }
void Pushup(int x)
{
if(Max[lson[x]]>=Max[rson[x]]) Max[x]=Max[lson[x]],id[x]=id[lson[x]];
else Max[x]=Max[rson[x]],id[x]=id[rson[x]];
}
void Modify(int l,int r,int &x,int pos,int val)
{
if(!x) x=New(); if(l==r) {Max[x]+=val,id[x]=l;}
else
{
int mid=l+r>>1;
if(pos<=mid) Modify(l,mid,lson[x],pos,val);
else Modify(mid+1,r,rson[x],pos,val);
Pushup(x);
}
if(!Max[x]) id[x]=0;
}
int Merge(int l,int r,int u,int v)
{
if(!u||!v) return u|v;
int now=New(),mid=l+r>>1; if(l==r) Max[now]=Max[u]+Max[v],id[now]=l;
else lson[now]=Merge(l,mid,lson[u],lson[v]),rson[now]=Merge(mid+1,r,rson[u],rson[v]),Pushup(now);
Throw(u);Throw(v);
return now;
}
}T;
struct Tree
{
int top[100005],son[100005],siz[100005],fa[100005],dep[100005];
void dfs(int k,int Fa)
{
fa[k]=Fa,siz[k]=1,dep[k]=dep[Fa]+1;
for(int i=ls[k];i;i=s[i].next)
{
int to=s[i].to; if(to==Fa) continue;
dfs(to,k),siz[k]+=siz[to];
if(siz[son[k]]<siz[to]) son[k]=to;
} return ;
}
void dfs2(int k,int to)
{
top[k]=to; if(son[k]) dfs2(son[k],to);
for(int i=ls[k];i;i=s[i].next)
{
int to=s[i].to; if(to==fa[k]||to==son[k]) continue;
dfs2(to,to);
}
}
int lca(int u,int v)
{
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]]) swap(u,v);
u=fa[top[u]];
}
return dep[u]<dep[v]?u:v;
}
}S;
void dfs(int k,int fa)
{
for(int i=ls[k];i;i=s[i].next) if(s[i].to!=fa) dfs(s[i].to,k);
for(int i=T.ls[k];i;i=T.s[i].next) T.Modify(1,100000,T.rt[k],T.s[i].to,T.s[i].op);
ans[k]=T.id[T.rt[k]];
if(S.fa[k]) T.rt[S.fa[k]]=T.Merge(1,100000,T.rt[S.fa[k]],T.rt[k]);
return ;
}
int main()
{
n=read(),m=read();
for(int i=1;i<n;++i)
{
int x=read(),y=read();
Insert(x,y),Insert(y,x);
}
S.dfs(1,0);S.dfs2(1,1);
for(int i=1;i<=m;++i)
{
int u=read(),v=read(),val=read();
int lca=S.lca(u,v),Flca=S.fa[lca];
T.Insert(u,val,1);T.Insert(v,val,1);T.Insert(lca,val,-1);T.Insert(Flca,val,-1);
}
dfs(1,0);
for(int i=1;i<=n;++i) printf("%d\n",ans[i]);
return 0;
}