Topic Analysis:
This kind of messy topic is a point of division, the answer is monotonous, so you can also answer two points.
We consider whether the answer will be greater than or equal to a certain value each time we are two minutes, noting that the coefficient $k$ is meaningless, because we can make $k=0$ by conversion.
The process of merging is equivalent to a number of vectors, which add up to look at the slope.
Note that a single vector also needs to be judged.
With a two-point answer, $ans$. The decision has become much simpler, push it.
$-k \leq \frac{a+c}{b+d} \leq k \rightarrow-k (b+d) \leq a+c \leq K (b+d) $.
Further $a+kb \geq-c-kd$ and $a-kb \leq kd-c$. Although there are four of dollars, but the order is interrelated, so the actual only two yuan, sorted after the tree array can be solved.
1#include <bits/stdc++.h>2 using namespacestd;3 4typedefLong Longll;5 6 Const intMAXN =50100;7 8ll K,MD;intFlag =0, Num,n,rnum;9Vector <pair<int,ll> >G[MAXN];Ten intARR[MAXN],SZ[MAXN],IMP[MAXN],CNT[MAXN]; One structNode{ll A;intB,pla;} OP[MAXN]; A - intCMP (node X,node Y) { - return-x.a-md*x.b <-y.a-md*y.b; the } - - structfenwick{ - intC[MAXN]; + voidADD (intNow ) { - while(now <= Rnum) {C[now] + +; now + = (now&-Now );} + } A intQueryintNow ) { at intAns =0; - while(now) {ans + = C[now]; now-= (now&-Now );} - returnans; - } - }t1; - in voidRead () { -scanf"%d%lld",&n,&k); to for(intI=1; i<n;i++){ + intx, y;Long LongV scanf"%d%d%lld", &x,&y,&v); V-=K; - G[x].push_back (Make_pair (y,v)); G[y].push_back (Make_pair (x,v)); the } * } $ Panax Notoginseng voidDFS1 (intNowintFaintDP) { -Sz[now] =1; Imp[now] =0; the for(Auto It:g[now]) { + if((Arr[it.first] && Arr[it.first] < DP) | | fa = = it.first)Continue; ADFS1 (IT.FIRST,NOW,DP); Sz[now] + =Sz[it.first]; the } + } - $ intDFS2 (intNowintFaintDpintSSZ) { $ intAns =0; - for(Auto It:g[now]) { - if((Arr[it.first] && Arr[it.first] < DP) | | fa = = it.first)Continue; the intdata =DFS2 (IT.FIRST,NOW,DP,SSZ); - if(ans==0|| Imp[ans] > Imp[data]) ans =data;WuyiImp[now] =Max (Sz[it.first],imp[now]); the } -Imp[now] = max (imp[now],ssz-Sz[now]); Wu if(ans==0|| Imp[ans] > Imp[now]) ans =Now ; - returnans; About } $ - voidDFS3 (intNowintFaintDpintAintB) { - for(Auto It:g[now]) { - if(It.first = = FA | | (Arr[it.first] && Arr[it.first] < DP))Continue; AOp[++num] = (node) {a+it.second,b+1, it.first}; +DFS3 (it.first,now,dp,a+it.second,b+1); the } - } $ the Long LongLISAN[MAXN]; the voidSolveintDR) { theRnum =num; the for(intI=1; i<=num;i++) {lisan[i] =-op[i]. a+md*Op[i]. B;} -Sort (lisan+1, lisan+num+1); rnum = Unique (lisan+1, lisan+num+1)-lisan-1; in for(intI=1; i<=rnum;i++) T1. c[i]=0; the for(inti=num,j=1; i>=1; i--){ the while(J <= Num && (-op[j]. A-MD*OP[J]. B < Op[i]. a+md*Op[i]. B)) { AboutT1. ADD (Lower_bound (lisan+1, lisan+rnum+1,-op[j]. A+MD*OP[J]. B)-Lisan); theJ + +; the } the intans=j-1-t1.query (Upper_bound (lisan+1, lisan+rnum+1, Op[i]. A-md*op[i]. B)-lisan-1); + if(Op[i]. A-md*op[i]. B <-op[i]. A+md*op[i]. B && J > i) ans--; - if(dr = =1){ the if(Ans-cnt[op[i].pla]) {flag =1;return;}Bayi}Else{Cnt[op[i].pla] =ans;} the } the } - - voidDivideintNowintDpintLstLong LongAA) { theDFS1 (now,0, DP);intHeavy = DFS2 (now,0, Dp,sz[now]); Arr[heavy] =DP; the for(Auto It:g[heavy]) { the if(ARR[IT.FIRST]&&ARR[IT.FIRST]<DP)Continue; theDivide (it.first,dp+1, Heavy,it.second); - if(Flag = =1)return; the } thenum =0; DFS3 (Heavy,0Dp0,0); Sort (op+1, op+num+1, CMP); theSolve1); num =0;94 if(LST) { thenum =0;d FS3 (now,0, DP,AA,1); theSort (op+1, op+num+1, CMP); the for(intI=1; i<=num;i++) Cnt[op[i].pla] =0;98Solve0); About } - }101 102 voidWork () {103 Long LongL =0, r =1e13;104 while(L <R) { themd = (l+r)/2; Flag =0;106memset (arr,0,sizeof(arr));107Divide1,1,0,0);108 if(flag) R = MD;ElseL = md+1;109 } theprintf"%lld", L-1);111 } the 113 intMain () { the read (); the Work (); the return 0;117}
UOJ276 [Tsinghua Training 2016] Soda "Two-point answer" "Points Division" "Tree-like array"