Test instructions n points form a tree with a bit of power. The length of the longest non-descending path, and the difference in the maximum minimum value of the path is not greater than D.
It is clear that the tree is divided, but how to maintain the answer after the partition.
Assuming that the current center of gravity is g, the length of the non-descending path of G is recorded, as well as the maximum value, the length of the non-ascending path and the minimum value respectively.
A map and two points are used here, and the segment tree is also possible, but if you are using a line tree, consider negative values, plus the clear of the line tree and a slightly violent query. The constant size is not good to say.
1#include <bits/stdc++.h>2 using namespacestd;3typedef pair <int,int>PII;4 Const intMAXN = 1e5 +5;5Vector <int>G[MAXN];6 intVAL[MAXN], SIZ[MAXN], N, D;7 BOOLCENTROID[MAXN];8 voidinit () {9 for(inti =0; i < MAXN; i++) {Ten g[i].clear (); One } Amemset (centroid,false,sizeofcentroid); - } - voidDfsintUintfather) { theSiz[u] =1; - for(intV:g[u]) { - if(V! = Father &&!Centroid[v]) { - Dfs (v, u); +Siz[u] + =Siz[v]; - } + } A } atPII findcentroid (intUintFatherintt) { -PII res = Make_pair (Int_max,-1); - ints =1, M =0; - for(intV:g[u]) { - if(v = = Father | |Centroid[v]) { - Continue; in } -res =min (res, findcentroid (V, U, t)); tom =Max (M, Siz[v]); +s + =Siz[v]; - } theSiz[u] =s; *m = max (M, ts); $ returnmin (res, Make_pair (M, u));Panax Notoginseng } -Map <int,int>Work ; the voidUpdateintVintLen) { +Auto it =Work.lower_bound (v); A if(It! = Work.end () && It->second >=Len) { the return; + } -WORK[V] =Len; $ } $ voidDFS_UP (intUintFatherintd) { - if(Val[u] >Val[father]) { - return; the } - Update (Val[u], d);Wuyi for(intV:g[u]) { the if(V! = Father &&!Centroid[v]) { -Dfs_up (V, u, d+1); Wu } - } About } $ intRes; - voidDfs_down (intUintFatherintd) { - if(Val[u] <Val[father]) { - return; A } +Auto it = Work.lower_bound (val[u]-D); the if(It! =Work.end ()) { -res = max (res, it->second+1+d); $ } the for(intV:g[u]) { the if(!centroid[v] && v! =father) { theDfs_down (V, u, d+1); the } - } in } the the voidPresolve (intG, Vector <int> &son) { About work.clear (); theWORK[VAL[G]] =0; the for(intV:son) { the if(Val[v] >=Val[g]) { +Dfs_down (V, G,1); - } the if(Val[v] <=Val[g]) {BayiDfs_up (V, G,1); the } the } - } - voidSolveintu) { theDFS (U,0); the intg = findcentroid (U,0, Siz[u]). Second; theVector <int>Son; the for(intV:g[g]) { - if(!Centroid[v]) { the Son.push_back (v); the } the }94 Presolve (g, son); the Reverse (Son.begin (), Son.end ()); the Presolve (g, son); theCENTROID[G] =true;98 for(intV:g[g]) { About if(!Centroid[v]) { - solve (v);101 }102 }103 }104 intMain () { the //freopen ("In.txt", "R", stdin);106 intT, CAS =1;107scanf ("%d", &T);108 while(t--) {109 init (); thescanf ("%d%d", &n, &D);111 for(inti =1; I <= N; i++) { thescanf ("%d", val+i);113 } the for(inti =1; I < n; i++) { the intu, v; thescanf ("%d%d", &u, &v);117 G[u].push_back (v);118 g[v].push_back (u);119 } -res =1;121Solve1);122printf"Case #%d:%d\n", cas++, res);123 }124 return 0; the}
Uvalive 7148 LRIP 14 Shanghai Regional Competition K Tree Division