深搜的过程中保存路径,二分路径中满足要求的区段。不必将每个节点的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