博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj1036
阅读量:6419 次
发布时间:2019-06-23

本文共 5038 字,大约阅读时间需要 16 分钟。

树链剖分的基本题

详细介绍在http://blog.sina.com.cn/s/blog_7a1746820100wp67.html
通过树链剖分我们就可以在树上做线段树操作,完成解答

1 const inf=2147483647;  2 type node=record  3        po,next:longint;  4      end;  5      point=record  6        max,sum:longint;  7      end;  8   9  10 var tree:array[0..120010] of point; 11     size,d,fa,p,b,c,top:array[0..30010] of longint; 12     w:array[0..80010] of node; 13     len,i,n,m,x,y,t:longint; 14     ch:char; 15     s:string; 16  17 function max(a,b:longint):longint; 18   begin 19     if a>b then exit(a) else exit(b); 20   end; 21  22 procedure update(i:longint); 23   begin 24     tree[i].sum:=tree[i*2].sum+tree[i*2+1].sum; 25     tree[i].max:=max(tree[i*2].max,tree[i*2+1].max); 26   end; 27  28 procedure swap(var a,b:longint); 29   var c:longint; 30   begin 31     c:=a; 32     a:=b; 33     b:=c; 34   end; 35  36 procedure add(x,y:longint); 37   begin 38     inc(len); 39     w[len].po:=y; 40     w[len].next:=p[x]; 41     p[x]:=len; 42   end; 43  44 procedure dfs1(x:longint);  //预处理 45   var i,y:longint; 46   begin 47     i:=p[x]; 48     size[x]:=1; 49     while i<>0 do 50     begin 51       y:=w[i].po; 52       if fa[x]<>y then 53       begin 54         fa[y]:=x; 55         d[y]:=d[x]+1; 56         dfs1(y); 57         size[x]:=size[x]+size[y]; 58       end; 59       i:=w[i].next; 60     end; 61   end; 62  63 procedure dfs2(x:longint); 64   var i,y,q:longint; 65   begin 66     i:=p[x]; 67     inc(t); 68     c[x]:=t; 69     q:=0; 70     while i<>0 do 71     begin 72       y:=w[i].po; 73       if (c[y]=0) and (size[q]
0 then 77 begin 78 top[q]:=top[x]; //重儿子先访问 79 dfs2(q); 80 end; 81 i:=p[x]; //然后访问轻儿子 82 while i<>0 do 83 begin 84 y:=w[i].po; 85 if c[y]=0 then 86 begin 87 top[y]:=y; 88 dfs2(y); 89 end; 90 i:=w[i].next; 91 end; 92 end; 93 94 procedure build(i,l,r:longint); 95 var m:longint; 96 begin 97 if l=r then 98 begin 99 tree[i].sum:=b[l];100 tree[i].max:=b[l];101 end102 else begin103 m:=(l+r) shr 1;104 build(i*2,l,m);105 build(i*2+1,m+1,r);106 update(i);107 end;108 end;109 110 procedure add(i,l,r:longint);111 var m:longint;112 begin113 if l=r then114 begin115 tree[i].sum:=y;116 tree[i].max:=y;117 end118 else begin119 m:=(l+r) shr 1;120 if x<=m then add(i*2,l,m) else add(i*2+1,m+1,r);121 update(i);122 end;123 end;124 125 function getmax(i,l,r,x,y:longint):longint;126 var m,t:longint;127 begin128 if (x<=l) and (y>=r) then exit(tree[i].max)129 else begin130 m:=(l+r) shr 1;131 t:=-inf;132 if x<=m then t:=max(t,getmax(i*2,l,m,x,y));133 if y>m then t:=max(t,getmax(i*2+1,m+1,r,x,y));134 exit(t);135 end;136 end;137 138 function getsum(i,l,r,x,y:longint):longint;139 var m,t:longint;140 begin141 if (x<=l) and (y>=r) then exit(tree[i].sum)142 else begin143 m:=(l+r) shr 1;144 t:=0;145 if x<=m then t:=t+getsum(i*2,l,m,x,y);146 if y>m then t:=t+getsum(i*2+1,m+1,r,x,y);147 exit(t);148 end;149 end;150 151 function asksum(x,y:longint):longint;152 var f1,f2:longint;153 begin154 asksum:=0;155 f1:=top[x];156 f2:=top[y];157 while f1<>f2 do158 begin159 if d[f1]>=d[f2] then160 begin161 asksum:=asksum+getsum(1,1,n,c[f1],c[x]);162 x:=fa[f1];163 end164 else begin165 asksum:=asksum+getsum(1,1,n,c[f2],c[y]);166 y:=fa[f2];167 end;168 f1:=top[x];169 f2:=top[y];170 end;171 if c[x]>c[y] then swap(x,y);172 asksum:=asksum+getsum(1,1,n,c[x],c[y]);173 end;174 175 function askmax(x,y:longint):longint;176 var f1,f2,t:longint;177 begin178 t:=-inf;179 f1:=top[x];180 f2:=top[y];181 while f1<>f2 do //提取182 begin183 if d[f1]>=d[f2] then184 begin185 t:=max(t,getmax(1,1,n,c[f1],c[x]));186 x:=fa[f1];187 end188 else begin189 t:=max(t,getmax(1,1,n,c[f2],c[y]));190 y:=fa[f2];191 end;192 f1:=top[x];193 f2:=top[y];194 end;195 if c[x]>c[y] then swap(x,y);196 t:=max(t,getmax(1,1,n,c[x],c[y]));197 exit(t);198 end;199 200 begin201 readln(n);202 for i:=1 to n-1 do203 begin204 readln(x,y);205 add(x,y);206 add(y,x);207 end;208 d[1]:=1;209 dfs1(1);210 t:=0;211 top[1]:=1;212 dfs2(1);213 for i:=1 to n do214 read(b[c[i]]);215 build(1,1,n);216 readln(m);217 for i:=1 to m do218 begin219 read(ch);220 s:='';221 while ch<>' ' do222 begin223 s:=s+ch;224 read(ch);225 end;226 readln(x,y);227 if s='QMAX' then228 writeln(askmax(x,y))229 else if s='QSUM' then230 writeln(asksum(x,y))231 else if s='CHANGE' then232 begin233 x:=c[x];234 b[x]:=y;235 add(1,1,n);236 end;237 end;238 end.
View Code

 

转载于:https://www.cnblogs.com/phile/p/4473093.html

你可能感兴趣的文章
Activity 5秒 Broadcast 10秒 Service 20秒
查看>>
linux 上配置tomcat、mysql 开机启动
查看>>
定制rpm包-Yum环境搭建
查看>>
回滚机制——《亿级流量》
查看>>
PHP7 学习笔记(十)会话控制
查看>>
9.Java通过axis调用WebService
查看>>
.net反混淆脱壳工具de4dot的使用
查看>>
使用Spring+MySql实现读写分离(一)关于windows下安装mysql5.6
查看>>
查询mssql的死锁语句
查看>>
Linux内核中实现生产者与消费者(避免无效唤醒)【转】
查看>>
mysql 密码重置
查看>>
『TensorFlow』TFR数据预处理探究以及框架搭建
查看>>
黑马程序猿——15,String,StringBuffer,基本数据类型包装对象
查看>>
公式编辑器打的公式能改变颜色吗?
查看>>
05-maven学习-构建web项目
查看>>
Error处理: “非法字符: \65279”的解决办法
查看>>
H264 RTP封包原理(转载)
查看>>
HTML5与XML的区别
查看>>
原生JS和jQuery版实现文件上传功能
查看>>
【POJ 1716】Integer Intervals(差分约束系统)
查看>>