CF739BAlyona and a tree(树上差分,二分,树形DP)
Posted myx12345
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF739BAlyona and a tree(树上差分,二分,树形DP)相关的知识,希望对你有一定的参考价值。
题意:给出一棵有根树,树上每个点、每条边都有一个权值。
现在给出“控制”的定义:对一个点u,设点v在其子树上,且dis(u,v)≤av,则称u控制v。
要求求出每个点控制了多少个点
n (1?≤?n?≤?2·105). (1?≤?ai?≤?109) 1?≤?pi?≤?n, 1?≤?wi?≤?109)
思路:在学校CF有时上不去不知道为什么
对于确定的点i,计算它对哪些点有贡献
dis[i]-dis[u]<=a[i]
dis[u]<=a[i]-dis[i]满足二分性
倍增枚举深度最小的i能给它贡献的点j
树上差分部分就是 inc(fa[i]) dec(fa[j])
最后统计出来的答案就是它子树里的和
注意INT64
1 var f:array[0..210000,0..19]of longint; 2 head,vet,next,len,flag,a:array[0..410000]of longint; 3 dp,dep,dis:array[0..410000]of int64; 4 n,tot,i,x,y,l,r,mid,last,j:longint; 5 6 procedure add(a,b,c:longint); 7 begin 8 inc(tot); 9 next[tot]:=head[a]; 10 vet[tot]:=b; 11 len[tot]:=c; 12 head[a]:=tot; 13 end; 14 15 procedure dfs(u:longint); 16 var e,v,i:longint; 17 begin 18 flag[u]:=1; 19 for i:=1 to 19 do 20 begin 21 if dep[u]<(1<<i) then break; 22 f[u,i]:=f[f[u,i-1],i-1]; 23 end; 24 e:=head[u]; 25 while e<>0 do 26 begin 27 v:=vet[e]; 28 if flag[v]=0 then 29 begin 30 dep[v]:=dep[u]+1; 31 dis[v]:=dis[u]+len[e]; 32 f[v,0]:=u; 33 dfs(v); 34 end; 35 e:=next[e]; 36 end; 37 end; 38 39 procedure dfs2(u:longint); 40 var e,v:longint; 41 begin 42 flag[u]:=1; 43 e:=head[u]; 44 while e<>0 do 45 begin 46 v:=vet[e]; 47 if flag[v]=0 then 48 begin 49 dfs2(v); 50 dp[u]:=dp[u]+dp[v]; 51 end; 52 e:=next[e]; 53 end; 54 end; 55 56 function clac(x,y:longint):longint; 57 var i:longint; 58 begin 59 for i:=0 to 19 do 60 if y and (1<<i)>0 then x:=f[x,i]; 61 exit(x); 62 end; 63 64 begin 65 //assign(input,‘cf739B.in‘); reset(input); 66 //assign(output,‘cf739B.out‘); rewrite(output); 67 readln(n); 68 for i:=1 to n do read(a[i]); 69 for i:=2 to n do 70 begin 71 readln(x,y); 72 add(i,x,y); 73 add(x,i,y); 74 end; 75 dfs(1); 76 fillchar(flag,sizeof(flag),0); 77 for i:=1 to n do 78 begin 79 l:=1; r:=dep[i]; last:=i; 80 while l<=r do 81 begin 82 mid:=(l+r)>>1; 83 j:=clac(i,mid); 84 if dis[i]-dis[j]<=a[i] then begin last:=j; l:=mid+1; end 85 else r:=mid-1; 86 end; 87 dec(dp[f[last,0]]); 88 inc(dp[f[i,0]]); 89 end; 90 91 dfs2(1); 92 for i:=1 to n-1 do write(dp[i],‘ ‘); 93 write(dp[n]); 94 //close(input); 95 //close(output); 96 end.
以上是关于CF739BAlyona and a tree(树上差分,二分,树形DP)的主要内容,如果未能解决你的问题,请参考以下文章
Alyona and a tree CodeForces - 739B (线段树合并)
CF276E Little Girl and Problem on Trees 题解