CF739B

深搜的过程中保存路径,二分路径中满足要求的区段。不必将每个节点的ans加1,只需将合法区段末尾加1同时将开头减1来表示并保存在一个“前缀”数组中即可。最后再dfs一次累加得到答案。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <vector>
 4 #include <algorithm>
 5 #define MAXN 200000
 6 using namespace std;
 7 typedef long long ll;
 8 int n, a[MAXN + 5], res[MAXN + 5], path[MAXN + 5];
 9 ll sum[MAXN + 5], ans[MAXN + 5];
10 struct node
11 {
12     int to, cost;
13 };
14 vector<node> G[MAXN + 5];
15 void solve(int x, int d, ll s)
16 {
17     sum[d] = s;
18     path[d] = x;
19     int l = lower_bound(sum + 1, sum + d + 1, s - a[x]) - sum - 1;
20     res[path[d]]++;
21     res[path[l]]--;
22     for (int i = 0; i < G[x].size(); i++)
23     {
24         solve(G[x][i].to, d + 1, s + G[x][i].cost);
25     }
26 }
27 void dfs(int x)
28 {
29     ans[x] = res[x];
30     for (int i = 0; i < G[x].size(); i++)
31     {
32         dfs(G[x][i].to);
33         ans[x] += ans[G[x][i].to];
34     }
35 }
36 int main()
37 {
38     cin >> n;
39     for (int i = 1; i <= n; i++)
40     {
41         scanf("%d", &a[i]);
42     }
43     for (int i = 0; i < n - 1; i++)
44     {
45         int x, y;
46         scanf("%d %d", &x, &y);
47         node tmp;
48         tmp.to = i+2;
49         tmp.cost = y;
50         G[x].push_back(tmp);
51     }
52     solve(1, 1, 0);
53     dfs(1);
54     for (int i = 1; i <= n; i++)
55         printf("%I64d ", ans[i]-1);
56     puts("");
57     //("pause");
58     return 0;
59 }
时间: 2024-10-12 08:25:54

CF739B的相关文章

【CF739B】Alyona and a tree(树上差分,二分,树形DP)

题意:给出一棵有根树,树上每个点.每条边都有一个权值. 现在给出"控制"的定义:对一个点u,设点v在其子树上,且dis(u,v)≤av,则称u控制v. 要求求出每个点控制了多少个点 n (1?≤?n?≤?2·105).  (1?≤?ai?≤?109) 1?≤?pi?≤?n, 1?≤?wi?≤?109) 思路:在学校CF有时上不去不知道为什么 对于确定的点i,计算它对哪些点有贡献 dis[i]-dis[u]<=a[i] dis[u]<=a[i]-dis[i]满足二分性 倍增枚

CF739B Alyona and a tree 树上差分

题目描述 \(Alyona有一棵有 n个节点的树.这棵树的根节点是 1.在每个节点里,Alyona写了一个正整数,在节点 i 她写了正整数a_i .另外,她在这棵树上的每条边上写了一个正整数(不同边上可能有不同的数). 让我们定义 dist(v,u) 作为从 v 到 u 的简单路径上的边权和. 当且仅当 u 在 v 的子树中并且 dist(v,u)<=a_u,顶点 v 控制顶点 u(v!=u) .Alyona想在某些顶点定居.为了做到这件事,她想知道在每个节点 v 能控制几个节点.\) 对于\(

CF739B Alyona and a tree

倍增+差分 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N=2e5+10; #define int long long int n,a[N],f[N][21],ans[N],dis[N]; int Next[2*N],head[N],go[N*2],w[N*2],tot; inline void