Http://codeforces.com/problemset/problem/740/D
For each pair of <u, v>. Set Dis[u] to indicate the distance from root to u, then dis<u to V> is dis[v]-dis[u],
is to find out how many v make Dis[v]-dis[u] <= A[v] in its son. Then, because if V is determined, then dis[v] and a[v] are determined.
So convert the formula to Dis[v]-a[v] <= Dis[u].
Then you can brute-force enumerate each U, and then find in its son how many number is less than equal to it, this can be directly violent sub-block.
#include <cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<algorithm>#include<assert.h>#defineIOS Ios::sync_with_stdio (False)using namespacestd;#defineINF (0X3F3F3F3F)typedefLong Long intLL; #include<iostream>#include<sstream>#include<vector>#include<Set>#include<map>#include<queue>#include<string>Const intMAXN = 2e5 + -;structNode {intu, V, W; intTonext;} E[MAXN];intFIRST[MAXN];intnum;voidAddintUintVintW) {++num; E[NUM].U=u; E[NUM].V=v; E[NUM].W=W; E[num].tonext=First[u]; First[u]=num;}intA[MAXN];intANS[MAXN]; LL DP[MAXN];structLIST {intID; LL Val;} LIST[MAXN];intlenlist;intDFN;intL[MAXN];intR[MAXN];voidDfsintcur) {list[++lenlist].id =cur;//list[lenlist].val = a[cur];++DFN; L[cur]=DFN; for(inti = first[cur]; I i =E[i].tonext) { intv =e[i].v; DP[V]= Dp[e[i].u] +E[I].W; DFS (v); } R[cur]=DFN;} LL TOSORT[MAXN];voidWork () {intN; scanf ("%d", &N); for(inti =1; I <= N; ++i) {scanf ("%d", &A[i]); } for(inti =1; I <= N-1; ++i) {intFA, W; scanf ("%d%d", &FA, &W); Add (FA, I+1, W); } DFS (1); for(inti =1; I <= lenlist; ++i) {list[i].val= Dp[list[i].id]-A[list[i].id]; Tosort[i]=List[i].val;//printf ("%d", list[i].id);//printf ("%d%d\n", L[list[i].id], r[list[i].id]); } intMagic = (int) sqrt (lenlist); for(inti =1; I <=lenlist;) { if(I + Magic-1<=lenlist) {Sort (Tosort+ I, Tosort + i +Magic); } Else Break; I+=Magic; } for(inti =1; I <= N; ++i) { for(intj = L[i] +1; J <=R[i];) { if(j% Magic = =1&& J + Magic-1<=R[i]) { intpos = Upper_bound (Tosort + J, Tosort + j + Magic, Dp[i])-(Tosort + J-1); Ans[i]+ = pos-1; J+=Magic; } Else { if(Dp[i] >=list[j].val) {Ans[i]++; } J++; } } } for(inti =1; I <= N; ++i) {printf ("%d", Ans[i]); }}intMain () {#ifdef local freopen ("Data.txt","R", stdin);//freopen ("Data.txt", "w", stdout);#endifWork (); return 0;}View Code
D. Alyona and a tree formula conversion + block violence