这是一道树链剖分的题目
做法:1.对树进行剖分,在更新的区间段上的左端点,打(谷物种类,1)标记,表示谷物加入该区间段的节点,在右端点加1的位置,打(谷物种类,-1)标记,表示减去前面加上的谷物,消去对后面区间段的影响。
2.以谷物种类为下标,维护区间段内,谷物数量的最大值,还有,当前最大值的谷物种类。从左向右加入标记,即可求出答案。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<algorithm>
#include<iostream>
using namespace std;
#define clr(a,b) memset(a,b,sizeof(a))
const int INF=~(1<<(sizeof(int )*8-1));
typedef long long ll;
typedef pair<int,int > P;
#define MOD 1000000007
#define MAXN 100010
int n,m,q,tot;
int siz[MAXN],depth[MAXN],son[MAXN],par[MAXN],top[MAXN],id[MAXN],rak[MAXN];
int ans[MAXN];
vector<int> G[MAXN];
vector<P> sav[MAXN];
struct node{
int l,r;
int num;
int maxn;
int mid()
{
return (l+r)/2;
}
}tree[4*MAXN];
void build(int l,int r,int i)
{
tree[i].l=l;
tree[i].r=r;
tree[i].maxn=0;
tree[i].num=-1;
if(l==r) return;
int mid=tree[i].mid();
build(l,mid,i<<1);
build(mid+1,r,i<<1|1);
}
void update(int x,int val,int i)
{
if(tree[i].l==tree[i].r)
{
tree[i].num=x;
tree[i].maxn+=val;
return ;
}
int mid=tree[i].mid();
if(x<=mid) update(x,val,i<<1);
else update(x,val,i<<1|1);
if(tree[i<<1].maxn>=tree[i<<1|1].maxn)
tree[i].num=tree[i<<1].num;
else tree[i].num=tree[i<<1|1].num;
tree[i].maxn=max(tree[i<<1].maxn,tree[i<<1|1].maxn);
}
void init()
{
tot=0;
son[0]=0;
for(int i=1;i<=n;i++)
{
son[i]=-1;
G[i].clear();
sav[i].clear();
}
build(1,100000,1);
}
void dfs1(int u,int pre,int deep)
{
depth[u]=deep;
siz[u]=1;
par[u]=pre;
int tp=0;
for(int i=0,sz=G[u].size();i<sz;i++)
{
int v=G[u][i];
if(v!=pre)
{
dfs1(v,u,deep+1);
siz[u]+=siz[v];
if(siz[tp]<siz[v])
tp=v;
}
}
if(tp) son[u]=tp;
}
void dfs2(int u,int high)
{
top[u]=high;
id[u]=++tot;
rak[tot]=u;
if(son[u]!=-1)
dfs2(son[u],high);
for(int i=0,sz=G[u].size();i<sz;i++)
{
int v=G[u][i];
if(v!=par[u]&&v!=son[u])
dfs2(v,v);
}
}
void change(int x,int y,int val)
{
while(top[x]!=top[y])
{
if(depth[top[x]]<depth[top[y]]) swap(x,y);
sav[id[top[x]]].push_back(make_pair(val,1));
sav[id[x]+1].push_back(make_pair(val,-1));
x=par[top[x]];
}
if(depth[x]>depth[y]) swap(x,y);
sav[id[x]].push_back(make_pair(val,1));
sav[id[y]+1].push_back(make_pair(val,-1));
}
int main()
{
//freopen("in","r",stdin);
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0) break;
init();
for(int i=1;i<n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
G[a].push_back(b);
G[b].push_back(a);
}
dfs1(1,-1,1);
dfs2(1,1);
for(int i=1;i<=m;i++)
{
int x,y,val;
scanf("%d%d%d",&x,&y,&val);
change(x,y,val);
}
for(int i=1;i<=n;i++)
{
for(int j=0,sz=sav[i].size();j<sz;j++)
{
P tp=sav[i][j];
update(tp.first,tp.second,1);
//printf("%d %d %d\n",rak[i],tp.first,tp.second);
}
//printf("maxn:%d num:%d\n",tree[1].maxn,tree[1].num);
if(tree[1].maxn)
ans[rak[i]]=tree[1].num;
else ans[rak[i]]=0;
}
for(int i=1;i<=n;i++)
printf("%d\n",ans[i]);
}
}