版权声明:欢迎随便转载。 https://blog.csdn.net/a1214034447/article/details/82988982
题目链接:点击这里
解题思路;
懒人标记树链剖分更新区间最大值,然后每次查询区间内最大值有等于K的,之后改为-inf.
时间复杂度O(n*logn*logn)
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int mx = 1e5 + 10;
int num[mx],n,head[mx],tot,fa[mx];
int siz[mx],dep[mx],size,top[mx];
int L,R,m,K,ans[mx];
int add[mx<<2],Max[mx<<2];
int a[mx],b[mx],c[mx];
struct node
{
int son,nxt;
}Edge[mx<<1];
void AddEdge(int x,int y)
{
Edge[tot].son = y;
Edge[tot].nxt = head[x];
head[x] = tot++;
}
void dfs1(int x,int f)//求重儿子,深度,树大小等等
{
dep[x] = dep[f] + 1;
siz[x] = 1;
int p = 0,wei = 0;
for(int i=head[x];~i;i=Edge[i].nxt)
{
int son = Edge[i].son;
if(son==f) continue;
fa[son] = x;
dfs1(son,x);
siz[x] += siz[son];
if(siz[son]>siz[wei]) wei = son,p = i;
}
//把重儿子换到第一个
if(p) swap(Edge[head[x]].son,Edge[p].son);
}
void dfs2(int x,int f)//重链轻链编号
{
num[x] = ++size;
for(int i=head[x];~i;i=Edge[i].nxt)
{
int son = Edge[i].son;
if(son==f) continue;
if(i==head[x]) top[son] = top[x];//是不是重儿子
else top[son] = son;
dfs2(son,x);
}
}
void push_up(int rt)
{
Max[rt<<1] += add[rt];
Max[rt<<1|1] += add[rt];
add[rt<<1] += add[rt];
add[rt<<1|1] += add[rt];
add[rt] = 0;
}
void update(int l,int r,int rt)
{
if(L<=l&&r<=R){
add[rt]++;
Max[rt]++;
return ;
}
push_up(rt);
int mid = (l+r)>>1;
if(L<=mid) update(lson);
if(R>mid) update(rson);
Max[rt] = max(Max[rt<<1],Max[rt<<1|1]);
}
void mask(int x,int y)
{
int f1 = top[x],f2 = top[y];
while(f1!=f2){
if(dep[f1]<dep[f2]) swap(f1,f2),swap(x,y);
L = num[f1],R = num[x];
x = fa[f1],f1 = top[x];
update(1,n,1);
}
L = min(num[x],num[y]);
R = max(num[x],num[y]);
update(1,n,1);
}
void check(int l,int r,int rt,int cr)
{
if(Max[rt]<K) return ;
if(l==r){
ans[l] = cr;
Max[rt] = -inf;
return ;
}
push_up(rt);
int mid = (l+r)>>1;
check(lson,cr);check(rson,cr);
Max[rt] = max(Max[rt<<1],Max[rt<<1|1]);
}
int main()
{
scanf("%d%d%d",&n,&m,&K);
memset(head,-1,sizeof(head));
int u,v;
for(int i=1;i<n;i++){
scanf("%d%d",&u,&v);
AddEdge(u,v);
AddEdge(v,u);
}
for(int i=1;i<=m;i++) scanf("%d%d%d",a+i,b+i,c+i);
dfs1(1,0),dfs2(1,0);
for(int i=m;i>=1;i--){
mask(a[i],b[i]);
check(1,n,1,c[i]);
}
for(int i=1;i<=n;i++) printf("%d%c",ans[num[i]],i==n?'\n':' ');
return 0;
}