• 树链剖分入门


    声明


          树链剖分前置知识:链式前向星、线段树。

        模板题:洛谷 P3384 


        这里就转载别人的博客吧(内含C++标程)~

     

          
      1 type
      2         tree=record
      3                 data,delta,l,r:longint;
      4         end;
      5 var
      6         t:array[0..300001] of tree;
      7         size,fa,deep,son,top,dfn,a,rank,en,first,next:array[0..200001] of longint;
      8         cnt,tot,n,m,i,r,p,x,y,z,k:longint;
      9 procedure add(x,y:longint);
     10 begin
     11         inc(cnt);
     12         next[cnt]:=first[x];
     13         first[x]:=cnt;
     14         en[cnt]:=y;
     15 end;
     16 procedure down(tot:longint);
     17 begin
     18         t[tot*2].data:=(t[tot*2].data+t[tot].delta*(t[tot*2].r-t[tot*2].l+1) mod p) mod p;
     19         t[tot*2+1].data:=(t[tot*2+1].data+t[tot].delta*(t[tot*2+1].r-t[tot*2+1].l+1) mod p) mod p;
     20         t[tot*2].delta:=(t[tot*2].delta+t[tot].delta) mod p;
     21         t[tot*2+1].delta:=(t[tot*2+1].delta+t[tot].delta) mod p;
     22         t[tot].delta:=0;
     23 end;
     24 procedure dfs1(x,f:longint);
     25 var
     26         t,e:longint;
     27 begin
     28         fa[x]:=f;
     29         deep[x]:=deep[f]+1;
     30         size[x]:=1;
     31         t:=first[x];
     32         while t<>0 do
     33         begin
     34                 e:=en[t];
     35                 if e<>f then
     36                 begin
     37                         dfs1(e,x);
     38                         inc(size[x],size[e]);
     39                         if (son[x]=0) or (size[e]>size[son[x]]) then son[x]:=e;
     40                 end;
     41                 t:=next[t];
     42         end;
     43 end;
     44 procedure dfs2(x,f:longint);
     45 var
     46         t,e:longint;
     47 begin
     48         inc(tot);
     49         dfn[x]:=tot;
     50         top[x]:=f;
     51         rank[tot]:=x;
     52         if son[x]=0 then exit;
     53         dfs2(son[x],f);
     54         t:=first[x];
     55         while t<>0 do
     56         begin
     57                 e:=en[t];
     58                 if (e<>son[x]) and (e<>fa[x]) then dfs2(e,e);
     59                 t:=next[t];
     60         end;
     61 end;
     62 procedure build(tot,l,r:longint);
     63 var
     64         mid:longint;
     65 begin
     66         if l=r then
     67         begin
     68                 t[tot].data:=a[rank[l]] mod p;
     69                 t[tot].l:=l;
     70                 t[tot].r:=r;
     71                 exit;
     72         end;
     73         t[tot].l:=l;
     74         t[tot].r:=r;
     75         mid:=(t[tot].l+t[tot].r) div 2;
     76         build(tot*2,l,mid);
     77         build(tot*2+1,mid+1,r);
     78         t[tot].data:=(t[tot*2].data+t[tot*2+1].data) mod p;
     79 end;
     80 procedure changesubtree(l,r,c,tot:longint);
     81 var
     82         mid:longint;
     83 begin
     84         if (l<=t[tot].l) and (t[tot].r<=r) then
     85         begin
     86                 t[tot].data:=(t[tot].data+c*(t[tot].r-t[tot].l+1) mod p) mod p;
     87                 t[tot].delta:=(t[tot].delta+c) mod p;
     88                 exit;
     89         end;
     90         mid:=(t[tot].l+t[tot].r) div 2;
     91         if t[tot].delta<>0 then down(tot);
     92         if l<=mid then changesubtree(l,r,c,tot*2);
     93         if r>mid then changesubtree(l,r,c,tot*2+1);
     94         t[tot].data:=(t[tot*2].data+t[tot*2+1].data) mod p;
     95 end;
     96 function querysubtree(l,r,tot:longint):longint;
     97 var
     98         mid:longint;
     99 begin
    100         if (l<=t[tot].l) and (t[tot].r<=r) then exit(t[tot].data);
    101         mid:=(t[tot].l+t[tot].r) div 2;
    102         if t[tot].delta<>0 then down(tot);
    103         querysubtree:=0;
    104         if l<=mid then querysubtree:=(querysubtree+querysubtree(l,r,tot*2)) mod p;
    105         if r>mid then querysubtree:=(querysubtree+querysubtree(l,r,tot*2+1)) mod p;
    106 end;
    107 procedure changeedge(x,y,c:longint);
    108 begin
    109         while top[x]<>top[y] do
    110                 if deep[top[x]]>=deep[top[y]] then
    111                 begin
    112                         changesubtree(dfn[top[x]],dfn[x],c,1);
    113                         x:=fa[top[x]];
    114                 end else
    115                 begin
    116                         changesubtree(dfn[top[y]],dfn[y],c,1);
    117                         y:=fa[top[y]];
    118                 end;
    119         if dfn[x]<=dfn[y] then changesubtree(dfn[x],dfn[y],c,1)
    120                 else changesubtree(dfn[y],dfn[x],c,1);
    121 end;
    122 function queryedge(x,y:longint):longint;
    123 begin
    124         queryedge:=0;
    125         while top[x]<>top[y] do
    126                 if deep[top[x]]>=deep[top[y]] then
    127                 begin
    128                         queryedge:=(queryedge+querysubtree(dfn[top[x]],dfn[x],1)) mod p;
    129                         x:=fa[top[x]];
    130                 end else
    131                 begin
    132                         queryedge:=(queryedge+querysubtree(dfn[top[y]],dfn[y],1)) mod p;
    133                         y:=fa[top[y]];
    134                 end;
    135         if dfn[x]<=dfn[y] then queryedge:=(queryedge+querysubtree(dfn[x],dfn[y],1)) mod p
    136                 else queryedge:=(queryedge+querysubtree(dfn[y],dfn[x],1)) mod p;
    137 end;
    138 begin
    139         readln(n,m,r,p);
    140         for i:=1 to n do
    141                 read(a[i]);
    142         readln;
    143         for i:=1 to n-1 do
    144         begin
    145                 readln(x,y);
    146                 add(x,y);
    147                 add(y,x);
    148         end;
    149         dfs1(r,0);
    150         dfs2(r,r);
    151         build(1,1,n);
    152         for i:=1 to m do
    153         begin
    154                 read(k);
    155                 if k=1 then
    156                 begin
    157                         readln(x,y,z);
    158                         changeedge(x,y,z);
    159                 end else if k=2 then
    160                 begin
    161                         readln(x,y);
    162                         writeln(queryedge(x,y));
    163                 end else if k=3 then
    164                 begin
    165                         readln(x,z);
    166                         changesubtree(dfn[x],dfn[x]+size[x]-1,z,1);
    167                 end else
    168                 begin
    169                         readln(x);
    170                         writeln(querysubtree(dfn[x],dfn[x]+size[x]-1,1));
    171                 end;
    172         end;
    173 end.
    然后附 Pascal 标程
  • 相关阅读:
    android基础开发之一setContentView用法
    setContentView( )方法
    如何使用andriod的布局标签
    也谈layout_gravity和gravity的用法
    SlidingMenu第二篇 --- SlidingMenu常用属性介绍
    SlidingMenu第一篇 --- 导入SlidingMenu库
    JS----对象的合并与克隆
    angular2 ----字符串、对象、base64 之间的转换
    WebStorm过期解决方法
    JavaScript--鼠标滚动改变图片大小
  • 原文地址:https://www.cnblogs.com/t-s-y/p/11319528.html
Copyright © 2020-2023  润新知