BZOJ3307 雨天的尾巴
题目链接:戳我
树上链修改->差分
每一个节点都开一个权值线段树,最后从下往上合并qwq
代码如下:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define MAXN 200010
using namespace std;
int t,n,m,cnt,cur_cnt;
int maxx[MAXN<<5],head[MAXN],ans[MAXN],dep[MAXN],x[MAXN],y[MAXN],z[MAXN],cur[MAXN],id[MAXN];
int fa[MAXN][21],rt[MAXN],ls[MAXN<<5],rs[MAXN<<5];
struct Edge{int nxt,to;}edge[MAXN<<1];
inline void add(int from,int to){edge[++t].nxt=head[from],edge[t].to=to,head[from]=t;}
inline void push_up(int x){maxx[x]=max(maxx[ls[x]],maxx[rs[x]]);}
inline void modify(int &x,int l,int r,int pos,int k)
{
if(!x) x=++cnt;
if(l==r) {maxx[x]+=k;return;}
int mid=(l+r)>>1;
if(pos<=mid) modify(ls[x],l,mid,pos,k);
else modify(rs[x],mid+1,r,pos,k);
push_up(x);
}
inline int merge(int x,int y,int l,int r)
{
if(!x||!y) return x+y;
if(l==r) {maxx[x]+=maxx[y];return x;}
int mid=(l+r)>>1;
ls[x]=merge(ls[x],ls[y],l,mid);
rs[x]=merge(rs[x],rs[y],mid+1,r);
push_up(x);
return x;
}
inline int query(int x,int l,int r)
{
if(l==r) return l;
int mid=(l+r)>>1;
if(maxx[x]==maxx[ls[x]]) return query(ls[x],l,mid);
else return query(rs[x],mid+1,r);
}
inline void dfs1(int x,int ff)
{
for(int i=1;i<=20;i++) fa[x][i]=fa[fa[x][i-1]][i-1];
for(int i=head[x];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(v==fa[x][0]) continue;
dep[v]=dep[x]+1;fa[v][0]=x;
dfs1(v,x);
}
}
inline int lca(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
int tt=dep[x]-dep[y];
for(int i=0;i<21;i++)
if(tt&(1<<i))
x=fa[x][i];
if(x==y) return x;
for(int i=20;i>=0;i--)
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
inline void solve(int x,int ff)
{
for(int i=head[x];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(v==ff) continue;
solve(v,x);
rt[x]=merge(rt[x],rt[v],1,cur_cnt);
}
if(!maxx[rt[x]]) ans[x]=0;
else ans[x]=id[query(rt[x],1,cur_cnt)];
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v),add(v,u);
}
for(int i=1;i<=m;i++) scanf("%d%d%d",&x[i],&y[i],&z[i]);
memcpy(cur,z,sizeof(z));
sort(&cur[1],&cur[1+m]);
cur_cnt=unique(&cur[1],&cur[1+m])-cur-1;
for(int i=1;i<=m;i++)
{
int kkk=lower_bound(&cur[1],&cur[1+cur_cnt],z[i])-cur;
id[kkk]=z[i];
z[i]=kkk;
}
dfs1(1,1);
for(int i=1;i<=m;i++)
{
modify(rt[x[i]],1,cur_cnt,z[i],1);
modify(rt[y[i]],1,cur_cnt,z[i],1);
int LCA=lca(x[i],y[i]);
modify(rt[LCA],1,cur_cnt,z[i],-1);
if(fa[LCA])
modify(rt[fa[LCA][0]],1,cur_cnt,z[i],-1);
}
solve(1,1);
for(int i=1;i<=n;i++)
printf("%d\n",ans[i]);
}