一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身
多余的分析就不需要了 上面讲树链剖分就是以这道题为例的
感谢黄学长的模板看了一遍就完全理解了 而且写得很漂亮
代码略长,以后可以多写写练练手感
1 program bzoj1036; 2 const maxn=30010;maxm=60010; 3 var n,i,j,x,y,q,cnt,t:longint; 4 ch:char; 5 ter,next:array[-1..maxm]of longint; 6 deep,pos,size,link,belong,v:array[-1..maxn]of longint; 7 fa:array[-1..maxn,-1..15]of longint; 8 tr:array[-1..5*maxn]of record l,r,mx,sum:longint;end; 9 10 function max(a,b:longint):longint; 11 begin 12 if a>b then exit(a) else exit(b); 13 end; 14 15 procedure add(x,y:longint); 16 begin 17 inc(j);ter[j]:=y;next[j]:=link[x];link[x]:=j; 18 inc(j);ter[j]:=x;next[j]:=link[y];link[y]:=j; 19 end; 20 21 procedure dfs1(p:longint); 22 var j:longint; 23 begin 24 size[p]:=1; 25 for i:=1 to 14 do 26 begin 27 if deep[p]<=1 << i then break; 28 fa[p][i]:=fa[fa[p][i-1]][i-1]; 29 end; 30 j:=link[p]; 31 while j<>0 do 32 begin 33 if deep[ter[j]]=0 then 34 begin 35 deep[ter[j]]:=deep[p]+1; 36 fa[ter[j]][0]:=p; 37 dfs1(ter[j]); 38 inc(size[p],size[ter[j]]); 39 end; 40 j:=next[j]; 41 end; 42 end; 43 44 procedure dfs2(p,chain:longint); 45 var k,j:longint; 46 begin 47 inc(cnt);pos[p]:=cnt;belong[p]:=chain; 48 k:=0; 49 j:=link[p]; 50 while j<>0 do 51 begin 52 if deep[ter[j]]>deep[p] then 53 if size[ter[j]]>size[k] then k:=ter[j]; 54 j:=next[j]; 55 end; 56 if k=0 then exit; 57 dfs2(k,chain); 58 j:=link[p]; 59 while j<>0 do 60 begin 61 if deep[ter[j]]>deep[p] then 62 if ter[j]<>k then dfs2(ter[j],ter[j]); 63 j:=next[j]; 64 end; 65 end; 66 67 procedure build(p,l,r:longint); 68 var mid:longint; 69 begin 70 tr[p].l:=l;tr[p].r:=r;tr[p].sum:=0;tr[p].mx:=-maxlongint; 71 if l=r then exit; 72 mid:=(l+r) >> 1; 73 build(p << 1,l,mid); 74 build(p << 1+1,mid+1,r); 75 end; 76 77 procedure insert(p,loc,x:longint); 78 var mid:longint; 79 begin 80 if (tr[p].l=loc)and(tr[p].r=loc) then 81 begin 82 tr[p].sum:=x;tr[p].mx:=x; 83 exit; 84 end; 85 mid:=(tr[p].l+tr[p].r) >> 1; 86 if loc<=mid then insert(p << 1,loc,x) else insert(p << 1+1,loc,x); 87 tr[p].sum:=tr[p << 1].sum+tr[p << 1+1].sum; 88 tr[p].mx:=max(tr[p << 1].mx,tr[p << 1+1].mx); 89 end; 90 91 function lca(x,y:longint):longint; 92 var i,tem:longint; 93 begin 94 if deep[x]<deep[y] then 95 begin 96 tem:=x;x:=y;y:=tem; 97 end; 98 if deep[x]<>deep[y] then 99 begin 100 i:=trunc(ln(deep[x]-deep[y])/ln(2)); 101 while deep[x]>deep[y] do 102 begin 103 while (deep[x]-deep[y]>=1 << i) do x:=fa[x][i]; 104 dec(i); 105 end; 106 end; 107 if x=y then exit(x); 108 i:=trunc(ln(n)/ln(2)); 109 while fa[x][0]<>fa[y][0] do 110 begin 111 while fa[x][i]<>fa[y][i] do 112 begin 113 x:=fa[x][i];y:=fa[y][i]; 114 end; 115 dec(i); 116 end; 117 exit(fa[x][0]); 118 end; 119 120 function query_sum(p,l,r:longint):longint; 121 var mid:longint; 122 begin 123 if (tr[p].l=l)and(tr[p].r=r) then exit(tr[p].sum); 124 mid:=(tr[p].l+tr[p].r) >> 1; 125 if r<=mid then exit(query_sum(p << 1,l,r)) else 126 if l>mid then exit(query_sum(p << 1+1,l,r)) else 127 exit(query_sum(p << 1,l,mid)+query_sum(p << 1+1,mid+1,r)); 128 end; 129 130 function query_mx(p,l,r:longint):longint; 131 var mid:longint; 132 begin 133 if (tr[p].l=l)and(tr[p].r=r) then exit(tr[p].mx); 134 mid:=(tr[p].l+tr[p].r) >> 1; 135 if r<=mid then exit(query_mx(p << 1,l,r)) else 136 if l>mid then exit(query_mx(p << 1+1,l,r)) else 137 exit(max(query_mx(p << 1,l,mid),query_mx(p << 1+1,mid+1,r))); 138 end; 139 140 function solve_sum(x,y:longint):longint; 141 var sum:longint; 142 begin 143 sum:=0; 144 while belong[x]<>belong[y] do 145 begin 146 inc(sum,query_sum(1,pos[belong[x]],pos[x])); 147 x:=fa[belong[x]][0]; 148 end; 149 inc(sum,query_sum(1,pos[y],pos[x])); 150 exit(sum); 151 end; 152 153 function solve_mx(x,y:longint):longint; 154 var mx:longint; 155 begin 156 mx:=-maxlongint; 157 while belong[x]<>belong[y] do 158 begin 159 mx:=max(mx,query_mx(1,pos[belong[x]],pos[x])); 160 x:=fa[belong[x]][0]; 161 end; 162 mx:=max(mx,query_mx(1,pos[y],pos[x])); 163 exit(mx); 164 end; 165 166 begin 167 readln(n); 168 for i:=1 to n-1 do 169 begin 170 readln(x,y); 171 add(x,y); 172 end; 173 deep[1]:=1;dfs1(1);cnt:=0;dfs2(1,1); 174 build(1,1,n); 175 for i:=1 to n do 176 begin 177 read(v[i]); 178 insert(1,pos[i],v[i]); 179 end; 180 readln(q); 181 for i:=1 to q do 182 begin 183 read(ch); 184 if ch=‘C‘ then 185 begin 186 readln(ch,ch,ch,ch,ch,x,y); 187 v[x]:=y; 188 insert(1,pos[x],y); 189 end else 190 begin 191 read(ch); 192 if ch=‘M‘ then 193 begin 194 readln(ch,ch,x,y); 195 t:=lca(x,y); 196 writeln(max(solve_mx(x,t),solve_mx(y,t))); 197 end else 198 begin 199 readln(ch,ch,x,y); 200 t:=lca(x,y); 201 writeln(solve_sum(x,t)+solve_sum(y,t)-v[t]); 202 end; 203 end; 204 end; 205 end.