浅谈--树上差分
推荐博客 : https://www.cnblogs.com/ice-wing/p/7709311.html
此类问题要解决的通常是 树上的某个点到另一个点的所有路径
差分 :
对于一个一维的数组,我们如果要改动态多次修改一个区间,比如给这个区间的所有值全部 加 1,那么我们是不在这个区间的头进行一个 +1,区间的尾的下一个单元进行一个 -1 的操作 ,最后再去求一个前缀和 ,即是最后更新的结果 。
树上差分 :
同样的道理我们也是修改树上的一段区间, 但是这个地方有个点一定要注意一下,就是从树的叶子往上修改,靠近树的叶子的区间改成 +1 , 往上的地方改成 -1 。
Alyona has a tree with n vertices. The root of the tree is the vertex 1. In each vertex Alyona wrote an positive integer, in the vertex i she wrote ai. Moreover, the girl wrote a positive integer to every edge of the tree (possibly, different integers on different edges).
Let's define dist(v, u) as the sum of the integers written on the edges of the simple path from v to u.
The vertex v controls the vertex u (v ≠ u) if and only if u is in the subtree of v and dist(v, u) ≤ au.
Alyona wants to settle in some vertex. In order to do this, she wants to know for each vertex v what is the number of vertices u such that v controls u.
The first line contains single integer n (1 ≤ n ≤ 2·105).
The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 109) — the integers written in the vertices.
The next (n - 1) lines contain two integers each. The i-th of these lines contains integers pi and wi (1 ≤ pi ≤ n, 1 ≤ wi ≤ 109) — the parent of the (i + 1)-th vertex in the tree and the number written on the edge between pi and (i + 1).
It is guaranteed that the given graph is a tree.
Print n integers — the i-th of these numbers should be equal to the number of vertices that the i-th vertex controls.
5
2 5 1 4 6
1 7
1 1
3 5
3 6
1 0 1 0 0
5
9 7 8 6 5
1 1
2 1
3 1
4 1
4 3 2 1 0
In the example test case the vertex 1 controls the vertex 3, the vertex 3 controls the vertex 5 (note that is doesn't mean the vertex 1 controls the vertex 5).
题目分析 : 题目定义了一种新的归属关系, dis(u, v) <= au, 那么 u 是属于 v 的孩子, 最后问你所有的点的孩子是多少
思路分析 : 对于给一个公式的题目首先就是要变形, dep[u]-dep[v] <= au, 变为 dep[u]-a[u] <= dep[v] ,dep 的含义就是到当前的深度是多少?那么它一定就是一个递增的数组,那么对于一个点我们不就是可以去二分它上面的所有点,找到一个符合的到当前的点都是符合题意的。
代码示例 :
#define ll long long const ll eps = 2e5+5; const double pi = acos(-1.0); const ll inf = 1<<29; #define Max(a,b) a>b?a:b #define Min(a,b) a>b?b:a ll n; ll pre[eps]; struct node { ll to, cost; node(ll _to, ll _cost):to(_to), cost(_cost){} }; vector<node>ve[eps]; ll dep[eps], path[eps]; ll cnt[eps], ans[eps]; void dfs(ll x, ll k, ll len){ dep[k] = len; path[k] = x; if (k > 1) { ll f = lower_bound(dep+1, dep+k, dep[k]-pre[x]) - dep; cnt[path[f-1]]--; cnt[path[k-1]]++; } for(ll i = 0; i < ve[x].size(); i++){ ll to = ve[x][i].to; ll cost = ve[x][i].cost; dfs(to, k+1, len+cost); } } void dfs2(ll x){ ans[x] = cnt[x]; for(ll i = 0; i < ve[x].size(); i++){ ll to = ve[x][i].to; dfs2(to); ans[x] += ans[to]; } } int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); cin >> n; ll p, w; for(ll i = 1; i<= n; i++){ scanf("%lld", &pre[i]); } for(ll i = 2; i <= n; i++){ scanf("%lld%lld", &p, &w); ve[p].push_back(node(i, w)); } dfs(1, 1, 0); dfs2(1); for(ll i = 1; i <= n; i++){ printf("%lld%c", ans[i], i==n?'\n':' '); } return 0; }