• 【模板】树链剖分


    题目传送门

      1 type
      2     rec                                        =record
      3     l,r                                        :longint;    
      4     sum,lazy                                :int64;
      5 end;
      6 
      7 
      8 var
      9     n,m,r,mo,i,x,y,z,opt,tot,ll                :longint;
     10     pre,last,other                            :array[0..200050] of longint;
     11     num                                        :array[0..100050] of longint;
     12     a,key                                    :array[0..100050] of int64;
     13     t                                        :Array[0..300050] of rec;
     14     size,top,dep,father                        :array[0..100050] of longint;
     15     vis                                        :Array[0..100050] of boolean;
     16     mson                                    :Array[0..100050] of longint;
     17 
     18 procedure swap(var x,y:longint);
     19 var
     20     z                                        :longint;
     21 begin
     22     z:=x;
     23     x:=y;
     24     y:=z;
     25 end;
     26     
     27 procedure add(u,v:longint);
     28 begin
     29     inc(ll);
     30     pre[ll]:=last[u];
     31     last[u]:=ll;
     32     other[ll]:=v;
     33 end;
     34     
     35 procedure dfs(x:longint);
     36 var
     37     p,q                                        :longint;
     38 begin
     39     size[x]:=1;
     40     p:=last[x];
     41     while p<>0 do
     42     begin
     43         q:=other[p];
     44         if not vis[q] then
     45         begin
     46             father[q]:=x;
     47             vis[q]:=true;
     48             dfs(q);
     49             inc(size[x],size[q]);
     50             if size[mson[x]]<size[q] then mson[x]:=q;
     51         end;
     52         p:=pre[p];
     53     end;
     54 end;
     55 
     56 procedure make(x,topp,depp:longint);
     57 var
     58     p,q                                        :longint;
     59 begin
     60     inc(tot);
     61     num[x]:=tot;
     62     a[tot]:=key[x];
     63     top[x]:=topp;
     64     dep[x]:=depp;
     65     if mson[x]<>0 then
     66     begin
     67         vis[mson[x]]:=true;
     68         make(mson[x],topp,depp);
     69     end;
     70     p:=last[x];
     71     while p<>0 do
     72     begin
     73         q:=other[p];
     74         if (not vis[q]) and (q<>mson[x]) then
     75         begin
     76             vis[q]:=true;
     77             make(q,q,depp+1);
     78         end;
     79         p:=pre[p];
     80     end;
     81 end;
     82 
     83 procedure build(x,l,r:longint);
     84 var
     85     mid                                        :longint;
     86 begin
     87     t[x].l:=l; t[x].r:=r;
     88     if (t[x].l=t[x].r) then
     89     begin
     90         t[x].sum:=a[l] mod mo;
     91         exit;
     92     end;
     93     mid:=(t[x].l+t[x].r)>>1;
     94     build(x*2,l,mid);
     95     build(x*2+1,mid+1,r);
     96     t[x].sum:=(t[x*2].sum+t[x*2+1].sum) mod mo;
     97 end;
     98 
     99 procedure update(x:longint);
    100 begin
    101     t[x].sum:=(t[x].sum+t[x].lazy*(t[x].r-t[x].l+1)) mod mo;
    102     if t[x].l=t[x].r then
    103     begin
    104         t[x].lazy:=0;
    105         exit;
    106     end;
    107     t[x*2].lazy:=(t[x*2].lazy+t[x].lazy) mod mo;
    108     t[x*2+1].lazy:=(t[x*2+1].lazy+t[x].lazy) mod mo;
    109     t[x].lazy:=0;
    110 end;
    111 
    112 procedure change(x,l,r,y:longint);
    113 var
    114     mid                                        :longint;
    115 begin
    116     if (t[x].l=l) and (t[x].r=r) then
    117     begin
    118         t[x].lazy:=(t[x].lazy+y) mod mo;
    119         exit;
    120     end;
    121     if t[x].lazy<>0 then update(x);
    122     mid:=(t[x].l+t[x].r)>>1;
    123     if l>mid then change(x*2+1,l,r,y) else
    124     if r<=mid then change(x*2,l,r,y) else
    125     begin
    126         change(x*2,l,mid,y);
    127         change(x*2+1,mid+1,r,y);
    128     end;
    129     t[x].sum:=(t[x*2].sum+t[x*2+1].sum+t[x*2].lazy*(t[x*2].r-t[x*2].l+1)+t[x*2+1].lazy*(t[x*2+1].r-t[x*2+1].l+1)) mod mo;
    130 end;
    131 
    132 function find(x,l,r:longint):longint;
    133 var
    134     mid                                        :longint;
    135 begin
    136     if t[x].lazy<>0 then update(x);
    137     if (t[x].l=l) and (t[x].r=r) then exit(t[x].sum);
    138     mid:=(t[x].l+t[x].r)>>1;
    139     if l>mid then exit(find(x*2+1,l,r)) else
    140     if r<=mid then exit(find(x*2,l,r)) else
    141     exit((find(x*2,l,mid)+find(x*2+1,mid+1,r)) mod mo);
    142 end;
    143 
    144 procedure qchan(x,y,z:longint);
    145 begin
    146     if dep[x]>dep[y] then swap(x,y);
    147     while dep[x]<dep[y] do
    148     begin
    149         change(1,num[top[y]],num[y],z);
    150         y:=father[top[y]];
    151     end;
    152     while top[x]<>top[y] do
    153     begin
    154         change(1,num[top[x]],num[x],z);
    155         change(1,num[top[y]],num[y],z);
    156         x:=father[top[x]];
    157         y:=father[top[y]];
    158     end;
    159     x:=num[x];
    160     y:=num[y];
    161     if x>y then swap(x,y);
    162     change(1,x,y,z);
    163 end;
    164 
    165 function qfind(x,y:longint):int64;
    166 var
    167     ans                                        :int64;
    168 begin
    169     ans:=0;
    170     if dep[x]>dep[y] then swap(x,y);
    171     while dep[x]<dep[y] do
    172     begin
    173         ans:=(ans+find(1,num[top[y]],num[y])) mod mo;
    174         y:=father[top[y]];
    175     end;
    176     while top[x]<>top[y] do
    177     begin
    178         ans:=(ans+find(1,num[top[x]],num[x])) mod mo;
    179         ans:=(ans+find(1,num[top[y]],num[y])) mod mo;
    180         x:=father[top[x]];
    181         y:=father[top[y]];
    182     end;
    183     x:=num[x];
    184     y:=num[y];
    185     if x>y then swap(x,y);
    186     ans:=(ans+find(1,x,y)) mod mo;
    187     writeln(ans);
    188 end;
    189     
    190 begin
    191     read(n,m,r,mo);
    192     for i:=1 to n do read(key[i]);
    193     for i:=1 to n-1 do
    194     begin
    195         read(x,y);
    196         add(x,y);
    197         add(y,x);
    198     end;
    199     vis[r]:=true;
    200     dfs(r);
    201     fillchar(vis,sizeof(vis),false);
    202     vis[r]:=true;
    203     make(r,r,1);
    204     build(1,1,n);
    205     for i:=1 to m do
    206     begin
    207         read(opt);
    208         if opt=1 then
    209         begin
    210             read(x,y,z);
    211             qchan(x,y,z);
    212         end else
    213         if opt=2 then
    214         begin
    215             read(x,y);
    216             qfind(x,y);
    217         end else
    218         if opt=3 then 
    219         begin
    220             read(x,y);
    221             change(1,num[x],num[x]+size[x]-1,y);
    222         end else
    223         begin
    224             read(x);
    225             writeln(find(1,num[x],num[x]+size[x]-1));
    226         end;
    227     end;
    228 end.
    229     
    230     
  • 相关阅读:
    第二次冲刺 03
    第二次冲刺 02
    第二次冲刺 01
    程序员修炼三部曲阅读笔记03
    程序员修炼三部曲阅读笔记02
    团队项目计划会议
    课堂练习—购书
    构建之法阅读笔记03
    学习进度条十二
    课堂作业找水王2
  • 原文地址:https://www.cnblogs.com/zoewilly/p/6506704.html
Copyright © 2020-2023  润新知