Description
在这个问题中,给定一个值S和一棵树。在树的每个节点有一个正整数,问有多少条路径的节点总和达到S。路径中节点的深度必须是升序的。假设节点1是根节点,根的深度是0,它的儿子节点的深度为1。路径不必一定从根节点开始。
Input
第一行是两个整数N和S,其中N是树的节点数。
第二行是N个正整数,第i个整数表示节点i的正整数。
接下来的N-1行每行是2个整数x和y,表示y是x的儿子。
Output
输出路径节点总和为S的路径数量。
Sample Input
3 3
1 2 3
1 2
1 3
Sample Output
2
#include <bits/stdc++.h>
#define lowbit(x) x&(-x)
#define LL long long
#define digit (ch < '0' || ch > '9')
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
template <class T> inline void read(T &x) {
int flag = 1; x = 0;
register char ch = getchar();
while( digit) { if(ch == '-') flag = -1; ch = getchar(); }
while(!digit) { x = (x<<1)+(x<<3)+ch-'0'; ch = getchar(); }
x *= flag;
}
const int maxn = 100005;
int n,m,l,r,cnt,a[maxn];
int frm[maxn<<1],to[maxn<<1],head[maxn],dep[maxn];
LL ans,sum;
inline void add(int u, int v) { to[++cnt] = v; frm[cnt] = head[u]; head[u] = cnt; }
void dfs(int u, int f) {
dep[++r] = a[u]; sum += a[u];
while(sum > m) sum -= dep[++l];
if(sum == m) ans++;
for(int i = head[u]; i; i = frm[i]) {
if(to[i] == f) continue;
dfs(to[i], u);
}
sum -= dep[r--];
while(l && sum+dep[l] <= m) sum += dep[l--];
}
int main() {
read(n); read(m);
for(int i = 1; i <= n; i++) read(a[i]);
for(int u, v, i = 1; i < n; i++) read(u), read(v), add(u, v), add(v, u);
dfs(1, 1);
printf(AUTO, ans);
return 0;
}