TLE #5
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e5 + 5;
struct RANKED_SGT {
int tot, sum[N << 5], lc[N << 5], rc[N << 5];
inline void init () {
tot = 0, memset(sum, 0, sizeof(sum));
memset(lc, 0, sizeof(lc)), memset(rc, 0, sizeof(rc));
return ;
}
inline void modify (int & u, int v, int l, int r, int pos, int k) {
u = ++ tot, sum[u] = sum[v] + k, lc[u] = lc[v], rc[u] = rc[v];
if (l == r) return ;
int mid = (l + r) / 2;
if (pos <= mid) modify(lc[u], lc[v], l, mid, pos, k);
else modify(rc[u], rc[v], mid + 1, r, pos, k);
}
inline int query (int u, int l, int r, int p, int q) {
if (! u) return 0;
if (p <= l && r <= q) return sum[u];
int mid = (l + r) / 2, ans = 0;
if (p <= mid) ans += query(lc[u], l, mid, p, q);
if (q > mid) ans += query(rc[u], mid + 1, r, p, q);
return ans;
}
} t;
struct EDGE {
int v, w;
} ;
vector <EDGE> son[N];
inline void AddEdge (int u, int v, int w) { son[u].push_back(EDGE{v, w}); }
struct path {
int d1, d2;
inline bool operator < (const path & x) const {
return d2 < x.d2;
}
} arr[N];
int n, ans, tot, w, l, siz[N], mas[N], vis[N], pos[N];
inline void getRoot (int u, int fa, int & rt, int s) {
siz[u] = 1, mas[u] = 0;
for (auto v : son[u])
if (! vis[v.v] && v.v != fa) {
getRoot(v.v, u, rt, s), siz[u] += siz[v.v];
mas[u] = max(mas[u], siz[v.v]);
}
mas[u] = max(mas[u], s - siz[u]);
if (mas[u] < mas[rt]) rt = u;
}
inline void getDist (int u, int fa, int d1, int d2) {
if (d1 > l || d2 > w) return ;
arr[++ tot] = path{d1, d2};
for (auto v : son[u])
if (! vis[v.v] && v.v != fa)
getDist(v.v, u, d1 + 1, d2 + v.w);
}
inline int calc (int u, int d1, int d2) {
tot = 0, t.init(), getDist(u, 0, d1, d2);
sort (arr + 1, arr + 1 + tot);
int res = 0;
for (int i = 1; i <= tot; i ++) t.modify(pos[i], pos[i - 1], 0, n, arr[i].d1, 1);
for (int i = 1; i <= tot; i ++) {
int v = upper_bound(arr + 1, arr + 1 + tot, path{0, w - arr[i].d2}) - arr - 1;
res += t.query(pos[v], 0, n, 0, l - arr[i].d1);
if (2 * arr[i].d1 <= l && 2 * arr[i].d2 <= w) res ++;
}
return res / 2;
}
inline void solve (int u) {
ans += calc(u, 0, 0), vis[u] = 1;
int rt;
for (auto v : son[u])
if (! vis[v.v]) {
ans -= calc(v.v, 1, v.w);
rt = 0, getRoot(v.v, 0, rt, siz[v.v]);
solve(rt);
}
}
signed main () {
cin >> n >> l >> w;
for (int i = 2, v, w; i <= n; i ++) {
scanf("%lld%lld", & v, & w);
AddEdge(i, v, w), AddEdge(v, i, w);
}
int rt = 0;
mas[0] = 114514114541, getRoot(1, 0, rt, n), solve(rt);
cout << ans - n;
return 0;
}
160696793#