Description
深绘里一直很讨厌雨天。
灼热的天气穿透了前半个夏天,后来一场大雨和随之而来的洪水,浇灭了一切。
虽然深绘里家乡的小村落对洪水有着顽固的抵抗力,但也倒了几座老房子,几棵老树被连
根拔起,以及田地里的粮食被弄得一片狼藉。
无奈的深绘里和村民们只好等待救济粮来维生。
不过救济粮的发放方式很特别。
首先村落里的一共有n 座房屋,并形成一个树状结构。然后救济粮分m 次发放,每次选择
两个房屋(x,y),然后对于x 到y 的路径上(含x 和y) 每座房子里发放一袋z 类型的救济粮。
然后深绘里想知道,当所有的救济粮发放完毕后,每座房子里存放的最多的是哪种救济粮。
灼热的天气穿透了前半个夏天,后来一场大雨和随之而来的洪水,浇灭了一切。
虽然深绘里家乡的小村落对洪水有着顽固的抵抗力,但也倒了几座老房子,几棵老树被连
根拔起,以及田地里的粮食被弄得一片狼藉。
无奈的深绘里和村民们只好等待救济粮来维生。
不过救济粮的发放方式很特别。
首先村落里的一共有n 座房屋,并形成一个树状结构。然后救济粮分m 次发放,每次选择
两个房屋(x,y),然后对于x 到y 的路径上(含x 和y) 每座房子里发放一袋z 类型的救济粮。
然后深绘里想知道,当所有的救济粮发放完毕后,每座房子里存放的最多的是哪种救济粮。
Input
第一行两个正整数n,m,含义如题目所示。
接下来n-1 行,每行两个数(a,b),表示(a,b) 间有一条边。
再接下来m 行,每行三个数(x,y,z),含义如题目所示。
接下来n-1 行,每行两个数(a,b),表示(a,b) 间有一条边。
再接下来m 行,每行三个数(x,y,z),含义如题目所示。
Output
n 行,第i 行一个整数,表示第i 座房屋里存放的最多的是哪种救济粮,如果有多种救济粮
存放次数一样,输出编号最小的。
如果某座房屋里没有救济粮,则对应一行输出0。
存放次数一样,输出编号最小的。
如果某座房屋里没有救济粮,则对应一行输出0。
Sample Input
5 3
1 2
3 1
3 4
5 4
2 3 3
1 5 2
3 3 3
Sample Output
2
3
3
2
2
Data Constraint
对于20% 的数据,1<= n,m <= 100
对于50% 的数据,1 <= n,m <= 2000
对于100% 的数据,1 <= n;m <= 100000; 1 <= a, b, x, y <= n; 1 <= z <= 10^9
对于50% 的数据,1 <= n,m <= 2000
对于100% 的数据,1 <= n;m <= 100000; 1 <= a, b, x, y <= n; 1 <= z <= 10^9
题解
- 考虑如果是在一条链上的话要怎么做
- 那么我们可以在x处加一个加入z的标记,在y+1出加入一个删掉z的标记,然后用权值线段树扫一遍就好了
- 现在拓展到一棵树上,我们可以在x和y处加入一个加上z的标记,在lca和fa[lca]处加入一个删除z的标记,那么我们每次可以把子节点的线段树合并上来
- 然后处理标记信息,最后查询答案即可
代码
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <vector> 5 #define N 100010 6 using namespace std; 7 struct tree { int l,r,sum,v; }t[N*50]; 8 int n,m,cnt,deep[N],a[N],root[N],fa[N][18],ans[N]; 9 vector<int>e[N],p[N],q[N]; 10 void pushup(int x) { if (t[t[x].r].sum>t[t[x].l].sum) t[x].sum=t[t[x].r].sum,t[x].v=t[t[x].r].v; else t[x].sum=t[t[x].l].sum,t[x].v=t[t[x].l].v; } 11 void dfs(int x,int f,int dep) 12 { 13 fa[x][0]=f,deep[x]=dep,root[x]=x,cnt++; 14 for (int i=1;i<=17;i++) fa[x][i]=fa[fa[x][i-1]][i-1]; 15 for (int i=0;i<e[x].size();i++) if (e[x][i]!=f) dfs(e[x][i],x,dep+1); 16 } 17 int LCA(int x,int y) 18 { 19 if (deep[x]<deep[y]) swap(x,y); 20 for (int i=17;i>=0;i--) if (deep[fa[x][i]]>=deep[y]) x=fa[x][i]; 21 if (x==y) return x; 22 for (int i=17;i>=0;i--) if (fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i]; 23 return fa[x][0]; 24 } 25 int update(int &d,int l,int r,int x,int y) 26 { 27 if (!d) d=++cnt; 28 if (l==r) { t[d].sum+=y,t[d].v=l; return 0; } 29 int mid=l+r>>1; 30 if (x<=mid) update(t[d].l,l,mid,x,y); else update(t[d].r,mid+1,r,x,y); 31 pushup(d); 32 } 33 int merge(int x,int y,int l,int r) 34 { 35 if (!x) return y; 36 if (!y) return x; 37 if (l==r) { t[x].sum+=t[y].sum,t[x].v=l; return x; } 38 int mid=l+r>>1; 39 t[x].l=merge(t[x].l,t[y].l,l,mid),t[x].r=merge(t[x].r,t[y].r,mid+1,r); 40 pushup(x); return x; 41 } 42 void dfs1(int x,int pre) 43 { 44 for (int i=0;i<e[x].size();i++) if (e[x][i]!=pre) dfs1(e[x][i],x),merge(root[x],root[e[x][i]],1,N-10); 45 for (int i=0;i<p[x].size();i++) update(root[x],1,N-10,p[x][i],1); 46 for (int i=0;i<q[x].size();i++) update(root[x],1,N-10,q[x][i],-1); 47 ans[x]=t[root[x]].v; 48 } 49 int main() 50 { 51 scanf("%d%d",&n,&m); 52 for (int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y),e[x].push_back(y),e[y].push_back(x); 53 dfs(1,0,1); 54 for (int i=1,x,y,z;i<=m;i++) 55 { 56 scanf("%d%d%d",&x,&y,&z); 57 int lca=LCA(x,y); 58 p[x].push_back(z),p[y].push_back(z),q[lca].push_back(z); 59 if (fa[lca][0]) q[fa[lca][0]].push_back(z); 60 } 61 dfs1(1,0); 62 for (int i=1;i<=n;i++) printf("%d\n",ans[i]); 63 }