Description
给定一颗n个结点的无根树,树上的每个点有一个非负整数点权,定义一条路径的价值为路径上的点权和-路径的点权最大值。
给定参数p,我们想知道,有多少不同的树上简单路径,满足它的价值恰好是p的倍数。
注意:单点算作一个路径;u ≠ v时,(u,v)和(v,u)只算一次。
Data Constraint
对所有测试点,我们有:
n≤10^5,p≤10^7,val_i≤10^9
Hint
满足条件的路径有:(1,1),(2,2),(3,3),(4,4),(5,5),(1,4),(2,3),(2,5),(3,5)。
题解
考虑点剖
对于当前的一个重心,我们可以先处理出它到子树中每一条边的点权和以及点权的最大值,然后我们可以按点权最大值的大小排一次序,假设我们现在做到第i条边,则我们可以把前i-1条边放到一个桶里面,然后如果我们现在选两条边,较大那条一定是现在做到的那条边的最大值,然后就可以通过桶快速计算答案
注意点剖中两条边在同一个直系儿子的情况,所以再做一遍去重就好了
贴代码
var
a,b,s,cc:array[0..200005,1..2]of longint;
va,size,vis,dis:array[0..100005]of longint;
tong:array[0..10000005]of longint;
i,j,k,l,m,n,p,x,y,ma,t1,root:longint;
ans:int64;
function max(x,y:longint):longint;
begin
if x>y then exit(x) else exit(y);
end;
procedure qsort(l,r:longint);
var
i,j,mid:longint;
begin
i:=l;
j:=r;
mid:=a[(l+r) div 2,1];
repeat
while