cqyz oj | 树上差分 | 最近公共祖先 | 差分

时间:2019-08-28
本文章向大家介绍cqyz oj | 树上差分 | 最近公共祖先 | 差分,主要包括cqyz oj | 树上差分 | 最近公共祖先 | 差分使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Description

    给定含 n 个结点的无根树,有m个人在树上旅行,第i个人从u[i]出发,到v[i]结束。请你统计下面两个信息:
    1)、经过每个点的人数。
    2)、经过每条边的人数。

Input

    第一行包括两个正整数 n,m,表示树的节点数和人数,树结点从1到n编号。
    接下来n-1行描述树边情况,其中第i行包含2个整数ai, bi,表示第i条双向边连接ai和bi。注意,边的编号按输入顺序从1..n-1编号。
    接下来m行描述每个人的旅行信息:u[i]和v[i]。

Output

    第一行包含n个整数,第i个整数表示经过i号点的人数。
    第二行包含n-1个整数,第i个整数表示编号为经过编号为i的边的人数。

Sample Input 1

11 4
1 6
2 1
4 3
6 7
9 8
3 1
3 5
2 10
10 11
8 6
1 9
3 10
11 5
4 8

Sample Output 1

4 2 3 1 1 2 0 2 1 2 1
2 2 1 0 1 3 1 2 1 2

Hint

1<n,m<=300000


对于一个人从 u 走到 v,则路径 u->LCA(u,v)->v 上的所有点经过的人数增加 1,路径上所有边上经过的人数也或增加 1。前面我们已经介绍这类问题提在序列上如何用差分思想来优化算法,但这里是树,能否利用这个思想呢?答案是肯定的!
1、树上差分数组
设差分数组:(下面所提到的权值表示经过人数)
A[i] 表示结点 i 的权值与其“所有儿子结点权值和”的差。
B[i] 表示边 fa[i]->i 的权值与所有i->son[i]的边权值和的差。
那么我们现在来看一次修改:一个人从 u 走到 v,差分数组该如何修改:
该人走过的路径为 u->z->v,那么
对于点权差分数组有:
A[u]++, A[v]++,
A[z]--, A[fa[z]]--;
对于边权差分数组有:
B[u]++, B[v]++;
B[z]=B[z]-2;
2、差分数组前缀和
设点权前缀和为 SA[i],边权前缀和为 SB[i],编号为 id的边权为 sum[id]
1)、计算经过点 i 的人数:

原文地址:https://www.cnblogs.com/de-compass/p/11424960.html