zoukankan      html  css  js  c++  java
  • 【CF739B】Alyona and a tree(树上差分,二分,树形DP)

    题意:给出一棵有根树,树上每个点、每条边都有一个权值。

    现在给出“控制”的定义:对一个点u,设点v在其子树上,且dis(u,v)av,则称u控制v。

    要求求出每个点控制了多少个点

    n (1 ≤ n ≤ 2·105).  (1 ≤ ai ≤ 109) 1 ≤ pi ≤ n1 ≤ 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.
  • 相关阅读:
    [zz][openstack swift]0 swift介绍
    [zz]/usr、/var和/etc目录
    [zz]使用 watchdog 构建高可用性的 Linux 系统及应用
    [zz]sheep dog的readme
    [zz] Consistent Hashing Ring
    [zz]为什么这些死脑筋们在用 VI ?
    libvirt 网络
    [zz]libcapng
    libvirt 创建的文件
    电商购物网站如何调用第三方支付平台(支付宝,财付通,盛付通等)
  • 原文地址:https://www.cnblogs.com/myx12345/p/6129190.html
Copyright © 2011-2022 走看看