Description
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
我们首先可以树上差分一下贡献,然后线段树自下而上合并就好了.
(启发式合并应该更靠谱,然而我动态开点后并不会维护size,维护了反而可能MLE,最后暴力合并一发A了,只是卡了发评测...)
#include
#include
#include
#define maxn 100005
#define maxx 200005
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
inline void read(int& x)
{ char c=getchar();x=0;int y=1;
while(c<'0'||c>'9'){if(c=='-') y=-1;c=getchar();}
while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
x*=y;
}
const int VMAX=1e9;
inline int m_max(int x,int y){return x>y?x:y;}
int n,m,son[maxn],ssum[maxn],top[maxn],fa[maxn],dp[maxn],ans[maxn],num,hea[maxn];
struct road{int en,nex;}ro[maxx];
inline void add(int x,int y){ro[num].en=y;ro[num].nex=hea[x];hea[x]=num++;}
inline void dfs(int x,int y=0)
{ ssum[x]=1;fa[x]=y;dp[x]=dp[y]+1;
for(int i=hea[x];i!=-1;i=ro[i].nex)
{ int v=ro[i].en;
if(v==y) continue;
dfs(v,x);ssum[x]+=ssum[v];
if(!son[x]||ssum[son[x]]inline void redfs(int x,int y=1)
{ top[x]=y;
if(!son[x]) return;
redfs(son[x],y);
for(int i=hea[x];i!=-1;i=ro[i].nex)
{ int v=ro[i].en;
if(v!=fa[x]&&v!=son[x]) redfs(v,v);
}
}
inline int flca(int x,int y)
{ int t1=top[x],t2=top[y];
while(t1!=t2)
{ if(dp[t1]std::swap(t1,t2),std::swap(x,y);
x=fa[t1];t1=top[x];
}
if(dp[x]>dp[y]) std::swap(x,y);
return x;
}
struct tree
{ tree *lch,*rch;int ma;
tree():lch(NULL),rch(NULL),ma(0){}
inline int mval(){return this?this->ma:0;}
inline void mt(){this->ma=m_max(this->lch->mval(),this->rch->mval());}
}*root[maxn];
inline void update(tree*& now,int x,int l,int r,int z)
{ if(!now) now=new tree();
if(l==r){now->ma+=z;return;}
int mid=l+r>>1;
if(x<=mid) update(now->lch,x,l,mid,z);
else update(now->rch,x,mid+1,r,z);
now->mt();
}
inline void merge(tree*& x,tree* y,int l,int r)
{ if(!y) return;if(!x){x=y;return;}
if(l==r){x->ma+=y->ma;return;}
int mid=l+r>>1;
merge(x->lch,y->lch,l,mid);merge(x->rch,y->rch,mid+1,r);
x->mt();
}
inline int dfs4(tree* x,int y,int l,int r)
{ if(!x) return 0;
if(l==r) return l;
int mid=l+r>>1;
if(x->lch->mval()==y) return dfs4(x->lch,y,l,mid);
else return dfs4(x->rch,y,mid+1,r);
}
inline void dfs3(int x,int y=0)
{ for(int i=hea[x];i!=-1;i=ro[i].nex)
{ int v=ro[i].en;
if(v==y) continue;
dfs3(v,x);
merge(root[x],root[v],1,VMAX);
}
if(root[x]->mval())
ans[x]=dfs4(root[x],root[x]->mval(),1,VMAX);
}
int main()
{ read(n);read(m);int x=0,y=0,z=0;mem(hea,-1);
for(int i=1;i1);redfs(1);
for(int i=1;i<=m;++i)
{ read(x);read(y);read(z);
int tmp=flca(x,y);
update(root[x],z,1,VMAX,1);
update(root[y],z,1,VMAX,1);
update(root[tmp],z,1,VMAX,-1);
if(fa[tmp]) update(root[fa[tmp]],z,1,VMAX,-1);
}
dfs3(1);
for(int i=1;i<=n;++i) printf("%d\n",ans[i]);
return 0;
}