1 条题解
-
0
树上前缀和。
在树上找一条权值和为 s 的链,其中这个链上的点按深度递增(递减)(不同)
dfs 每搜到一个点求它的前缀和 sum[x],放入 set 中。
在 set 中找 sum[x] - s 的点,如果有,ans++
退出 dfs 的时候再把 sum[x] 从 set 中删除
因为每个点权都是正整数,所以 set 中没有重复元素。
同时也是单调递增,所以简单些不用 set,开个数组再 lower_bound 也行。
——代码
#include <bits/stdc++.h> using namespace std; const int MAXN = 100001; int n, s, cnt, ans; int a[MAXN], head[MAXN], to[MAXN << 1], nxt[MAXN << 1], f[MAXN], sum[MAXN]; std::set <int> S; inline void add(int x, int y) { to[cnt] = y; nxt[cnt] = head[x]; head[x] = cnt++; } inline void dfs(int u) { sum[u] = sum[f[u]] + a[u]; S.insert(sum[u]); if(S.count(sum[u] - s)) ans++; for(int i = head[u]; i ^ -1; i = nxt[i]) dfs(to[i]); S.erase(sum[u]); } int main() { int i, x, y; cin>>n>>s; memset(head, -1, sizeof(head)); for(i = 1; i <= n; i++) cin>>a[i]; for(i = 1; i < n; i++) { cin>>x>>y; f[y] = x; add(x, y); } S.insert(0); dfs(1); printf("%d\n", ans); return 0; }
- 1
信息
- ID
- 63
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 3
- 标签
- 递交数
- 131
- 已通过
- 68
- 上传者