• bzoj3631


    其实这道题其实可以转化为这样一个问题

    给定n-1对点,将这两点x,y间简单路径上的点(包括起点终点)权值+1

    (最后再把除了起点外的点的权值-1,注意终点没糖吃)

    求每个点的权值

    首先想到的是先找LCA然后暴力的对权值加,显然这样效率不够好

    想到了树状数组完成区间修改和单点求值,是先将[l,r]中a[l]++,然后a[r+1]--;

    这样就避免了对每个数都修改;

    以此类推,我们可以假定路径使x-->root-->y上的点+1,

    这样每个点的权值即为其所在子树和

    设lca(x,y)=z 同样的道理,我们只要对a[x]++,a[y]++,然后对a[z]--,a[fa[z]]--

    因为每个点的权值即为其所在子树和,所以只有x-->y的简单路径上的点权值+1了

    这样的话我们可以做一遍LCA-tarjan就可以搞出来了(当然也可以再单独扫一遍)

     1 type node=record
     2        po,next:longint;
     3        can:boolean;
     4      end;
     5  
     6 var a,q:array[0..600010] of node;
     7     fa,f,p,w,ans,g:array[0..300010] of longint;
     8     v:array[0..300010] of boolean;
     9     st,i,j,n,m,x,y,t:longint;
    10  
    11 function getf(x:longint):longint;
    12   begin
    13     if fa[x]<>x then fa[x]:=getf(fa[x]);
    14     exit(fa[x]);
    15   end;
    16  
    17 procedure addq(x,y:longint);
    18   begin
    19     inc(m);
    20     q[m].po:=y;
    21     q[m].next:=w[x];
    22     w[x]:=m;
    23   end;
    24  
    25 procedure add(x,y:longint);
    26   begin
    27     inc(t);
    28     a[t].po:=y;
    29     a[t].next:=p[x];
    30     p[x]:=t;
    31   end;
    32  
    33 procedure tarjan(x:longint);
    34   var i,y,z:longint;
    35   begin
    36     i:=p[x];
    37     v[x]:=true;
    38     while i<>0 do
    39     begin
    40       y:=a[i].po;
    41       if not v[y] then
    42       begin
    43         f[y]:=x;
    44         tarjan(y);
    45         fa[y]:=x;
    46       end;
    47       i:=a[i].next;
    48     end;
    49     i:=w[x];
    50     while i<>-1 do
    51     begin
    52       y:=q[i].po;
    53       if v[y] and not q[i].can then
    54       begin
    55         z:=getf(y);
    56         q[i].can:=true;
    57         q[i xor 1].can:=true;
    58         inc(g[z]);
    59         inc(g[f[z]]);
    60       end;
    61       i:=q[i].next;
    62     end;
    63     ans[x]:=ans[x]-g[x]; 
    64     ans[f[x]]:=ans[f[x]]+ans[x];//做到这已经说明x的子树已经被访问完了,x的权值已经确定,直接加即可,不需要再dfs一遍
    65   end;
    66  
    67 begin
    68   m:=-1;
    69   fillchar(w,sizeof(w),255);
    70   readln(n);
    71   read(x);
    72   st:=x;
    73   ans[x]:=1;
    74   for i:=1 to n-1 do
    75   begin
    76     read(y);
    77     addq(x,y);
    78     addq(y,x);
    79     inc(ans[y]);
    80     if i<>n-1 then inc(ans[y]);
    81     x:=y;
    82   end;
    83   for i:=1 to n-1 do
    84   begin
    85     readln(x,y);
    86     add(x,y);
    87     add(y,x);
    88   end;
    89   for i:=1 to n do
    90     fa[i]:=i;
    91  
    92   tarjan(1);
    93   for i:=1 to n do
    94   begin
    95     if i<>st then dec(ans[i]);
    96     writeln(ans[i]);
    97   end;
    98 end.
    View Code
  • 相关阅读:
    docker.service启动失败:Unit not found
    本地测试环境搭建
    2016 年总结
    node-http-proxy修改响应结果
    JavaScript那些事儿(01): 对象
    Javascript正则表达式
    addEventListener之handleEvent
    《CSS那些事儿》读书笔记
    《编写高质量代码--Web前端开发修炼之道》读书笔记
    Javascript闭包简单理解
  • 原文地址:https://www.cnblogs.com/phile/p/4473128.html
Copyright © 2020-2023  润新知