N个点,形成一个树状结构。有M次发放,每次选择两个点x,y
对于x到y的路径上(含x,y)每个点发一袋Z类型的物品。完成
所有发放后,每个点存放最多的是哪种物品。
Input
第一行数字N,M
接下来N-1行,每行两个数字a,b,表示a与b间有一条边
再接下来M行,每行三个数字x,y,z.如题
Output
输出有N行
每i行的数字表示第i个点存放最多的物品是哪一种,如果有
多种物品的数量一样,输出编号最小的。如果某个点没有物品
则输出0
范围
1<=N,M<=100000
1<=a,b,x,y<=N
1<=z<=10^9
如果在一个链上。
把操作(x,y,+1)拆成(x,r,+1)与(y+1,r,-1)。发现从左到右扫一遍,遍扫变统计前面的答案是与后面的询问无关的。
树上。。树链剖分拆成log个区间。把树拍成区间来做。。这题小细节比较多。。我估计要调一年的那种。
颜色编号最小,没有物品输出0。
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+5;
const int INF=1e9+7;
struct edge{
int to,next;
}e[MAXN<<1];
int head[MAXN],cnt=0;
inline void add(int u,int v){e[++cnt]=(edge){v,head[u]},head[u]=cnt;}
int fa[MAXN],size[MAXN],dep[MAXN],hson[MAXN];
void dfs1(int u,int father){
fa[u]=father;
size[u]=1;
dep[u]=dep[father]+1;
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==father)continue;
dfs1(v,u);
size[u]+=size[v];
if(!hson[u]||size[hson[u]]<size[v])hson[u]=v;
}
}
int top[MAXN],id[MAXN],rl[MAXN],num=0;
void dfs2(int u,int tp){
top[u]=tp;
id[u]=++num;
rl[num]=u;
if(hson[u])dfs2(hson[u],tp);
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==fa[u]||v==hson[u])continue;
dfs2(v,v);
}
}
int tot=0;
struct query{
int color,num;
};
vector<query>vec[MAXN];
map<int,int>ma,ma2;//ma 颜色->序号 ma2序号->颜色
int ans[MAXN];
int maxv[MAXN<<2],who[MAXN<<2];
typedef pair<int,int>par;
struct xds{
#define lson (o<<1)
#define rson (o<<1|1)
#define mp make_pair
inline void pushup(int o){
if(maxv[lson]==maxv[rson]){
maxv[o]=maxv[lson];
if(who[lson]<who[rson])who[o]=who[lson];
else who[o]=who[rson];
}
else if(maxv[lson]>maxv[rson])maxv[o]=maxv[lson],who[o]=who[lson];
else maxv[o]=maxv[rson],who[o]=who[rson];
}
void build(int o,int l,int r){
if(l==r){maxv[o]=0;who[o]=ma2[l];return;}
int mid=l+r>>1;
build(lson,l,mid);build(rson,mid+1,r);
pushup(o);
}
void change(int o,int l,int r,int pos,int val){
if(l==r){maxv[o]+=val;return;}
int mid=l+r>>1;
if(pos<=mid)change(lson,l,mid,pos,val);
else change(rson,mid+1,r,pos,val);
pushup(o);
}
par querymax(int o,int l,int r,int ql,int qr){
if(ql<=l&&qr>=r)return mp(maxv[o],who[o]);
int mid=l+r>>1;
par ans=mp(-INF,0),t1,t2;
if(ql<=mid)t1=querymax(lson,l,mid,ql,qr);
if(qr>mid)t2=querymax(rson,mid+1,r,ql,qr);
if(t1.first==t2.first){
if(t1.second<t2.second)ans=t1;
else ans=t2;
}
else if(t1.first<t2.first)ans=t1;
else ans=t2;
return ans;
}
}T;
int lca(int x,int y,int c){
int tx=top[x],ty=top[y];
while(tx!=ty){
if(dep[tx]<dep[ty]){
vec[id[ty]].push_back((query){c,1});
vec[id[y]+1].push_back((query){c,-1});
y=fa[ty];
}
else {
vec[id[tx]].push_back((query){c,1});
vec[id[x]+1].push_back((query){c,-1});
x=fa[tx];
}
tx=top[x],ty=top[y];
}
if(dep[x]<dep[y])swap(x,y);
vec[id[y]].push_back((query){c,1});
vec[id[x]+1].push_back((query){c,-1});
return y;
}
void getans(int n){
for(int i=1;i<=n;i++){
for(int j=0;j<vec[i].size();j++){
T.change(1,1,tot,vec[i][j].color,vec[i][j].num);
// cout<<i<<"::"<<vec[i][j].color<<" "<<vec[i][j].num<<endl;
}
par tmp=T.querymax(1,1,tot,1,tot);
if(tmp.first!=0)ans[rl[i]]=tmp.second;
else ans[rl[i]]=0;
}
}
int main(){
int n,m,u,v,w;
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dfs1(1,0);
dfs2(1,0);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
if(ma[w]==0)ma[w]=++tot,ma2[tot]=w;
lca(u,v,ma[w]);
}
T.build(1,1,tot);
getans(n);
for(int i=1;i<=n;i++)printf("%d\n",ans[i]);
return 0;
}