[POJ3237]Tree解题报告|树链剖分|边剖
关于边剖
之前做的大多是点剖,其实转换到边剖非常简单。
我的做法是每个点的点权记录其到父亲节点的边的边权。
只要solve的时候不要把最上面的点记录在内就可以了。
Tree
Description
You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edges are numbered 1 through N − 1. Each edge is associated with a weight. Then you are to execute a series of instructions on the tree. The instructions can be one of the following forms:
CHANGE
i vChange the weight of the ith edge to v NEGATE
a bNegate the weight of every edge on the path from a to b QUERY
a bFind the maximum weight of edges on the path from a to b
这道题除了边剖之外另一个难点是处理NEGATE操作
将从a到b路径上的边权都取反
其实思考一下便知只要存mx和mn两个值然后反转的时候互换并取反就可以了
但是出现了问题,我以前用的向下传递不对了
因为反转操作的存在,当前的值很可能被子节点中本来并不优秀但是反转了之后能比当前点更好的点取代
然而传统的情况下当(tr[p].l=l)and(tr[p].r=r)的时候就停止了
这就导致了可能当前的状态并不是最优秀的
我们用一个push操作先向下传递一遍并刷新当前的值
保证当前p节点里的值都是真实存在的
在每个过程里都先执行一次push操作
时间复杂度看上去或许并不乐观,但是实际上标记为真的个数并不多
像这样特殊的操作就需要这种保证正确性的传递方式
以后遇到类似的题要多加思考
(树链剖分的题代码量真的很大啊QAQ
1 program poj3237; 2 const maxn=10010;maxm=20010; 3 var test,t,x,y,z,cnt,tt,n,m,j,i:longint; 4 son,size,link,belong,deep,v,pos:array[-1..maxn]of longint; 5 ter,next,w:array[-1..maxm]of longint; 6 fa:array[-1..maxn,-1..20]of longint; 7 tr:array[-1..5*maxn]of record l,r,mx,mi:longint;wait,op:boolean;end; 8 ch:char; 9 10 function max(a,b:longint):longint; 11 begin 12 if a>b then exit(a) else exit(b); 13 end; 14 15 function min(a,b:longint):longint; 16 begin 17 if a<b then exit(a) else exit(b); 18 end; 19 20 procedure add(x,y,z:longint); 21 begin 22 inc(j);ter[j]:=y;next[j]:=link[x];link[x]:=j;w[j]:=z; 23 inc(j);ter[j]:=x;next[j]:=link[y];link[y]:=j;w[j]:=z; 24 end; 25 26 procedure dfs1(p:longint); 27 var i,j:longint; 28 begin 29 size[p]:=1; 30 for i:=1 to 15 do 31 begin 32 if deep[p]<=1 << i then break; 33 fa[p][i]:=fa[fa[p][i-1]][i-1]; 34 end; 35 j:=link[p]; 36 while j<>0 do 37 begin 38 if deep[ter[j]]=0 then 39 begin 40 deep[ter[j]]:=deep[p]+1; 41 fa[ter[j]][0]:=p; 42 v[ter[j]]:=w[j];son[(j+1) >> 1]:=ter[j]; 43 dfs1(ter[j]); 44 inc(size[p],size[ter[j]]); 45 end; 46 j:=next[j]; 47 end; 48 end; 49 50 procedure dfs2(p,chain:longint); 51 var j,k:longint; 52 begin 53 inc(cnt);pos[p]:=cnt;belong[p]:=chain; 54 k:=0; 55 j:=link[p]; 56 while j<>0 do 57 begin 58 if deep[ter[j]]>deep[p] then 59 if size[ter[j]]>size[k] then k:=ter[j]; 60 j:=next[j]; 61 end; 62 if k=0 then exit; 63 dfs2(k,chain); 64 j:=link[p]; 65 while j<>0 do 66 begin 67 if (deep[ter[j]]>deep[p])and(ter[j]<>k) then dfs2(ter[j],ter[j]); 68 j:=next[j]; 69 end; 70 end; 71 72 procedure build(p,l,r:longint); 73 var mid:longint; 74 begin 75 tr[p].l:=l;tr[p].r:=r;tr[p].mx:=-maxlongint;tr[p].mi:=maxlongint;tr[p].wait:=false;tr[p].op:=false; 76 if l=r then exit; 77 mid:=(l+r) >> 1; 78 build(p << 1,l,mid); 79 build(p << 1+1,mid+1,r); 80 end; 81 82 procedure push(p:longint); 83 var tem:longint; 84 begin 85 if tr[p].l=tr[p].r then exit; 86 if tr[p].wait then 87 begin 88 push(p << 1);push(p << 1+1); 89 tr[p << 1].mx:=max(tr[p].mx,tr[p << 1].mx);tr[p << 1].mi:=min(tr[p << 1].mi,tr[p].mi);tr[p << 1].wait:=true; 90 tr[p << 1+1].mx:=max(tr[p].mx,tr[p << 1+1].mx);tr[p << 1+1].mi:=min(tr[p << 1+1].mi,tr[p].mi);tr[p << 1+1].wait:=true; 91 tr[p].mx:=max(tr[p << 1].mx,tr[p << 1+1].mx); 92 tr[p].mi:=min(tr[p << 1].mi,tr[p << 1+1].mi); 93 tr[p].wait:=false; 94 end; 95 if tr[p].op then 96 begin 97 push(p << 1);push(p << 1+1); 98 tem:=tr[p << 1].mx;tr[p << 1].mx:=-tr[p << 1].mi;tr[p << 1].mi:=-tem;tr[p << 1].op:=true; 99 tem:=tr[p << 1+1].mx;tr[p << 1+1].mx:=-tr[p << 1+1].mi;tr[p << 1+1].mi:=-tem;tr[p << 1+1].op:=true; 100 tr[p].mx:=max(tr[p << 1].mx,tr[p << 1+1].mx); 101 tr[p].mi:=min(tr[p << 1].mi,tr[p << 1+1].mi); 102 tr[p].op:=false; 103 end; 104 end; 105 106 procedure insert(p,l,r,ave:longint); 107 var mid,tem:longint; 108 begin 109 push(p); 110 if (tr[p].l=l)and(tr[p].r=r) then 111 begin 112 tr[p].mx:=ave; 113 tr[p].mi:=ave; 114 tr[p].wait:=true; 115 exit; 116 end; 117 mid:=(tr[p].l+tr[p].r) >> 1; 118 if r<=mid then insert(p << 1,l,r,ave) else 119 if l>mid then insert(p << 1+1,l,r,ave) else 120 begin 121 insert(p << 1,l,mid,ave); 122 insert(p << 1+1,mid+1,r,ave); 123 end; 124 tr[p].mx:=max(tr[p << 1].mx,tr[p << 1+1].mx); 125 tr[p].mi:=min(tr[p << 1].mi,tr[p << 1+1].mi); 126 end; 127 128 function lca(x,y:longint):longint; 129 var tem,i:longint; 130 begin 131 if deep[x]<deep[y] then 132 begin 133 tem:=x;x:=y;y:=tem; 134 end; 135 if deep[x]<>deep[y] then 136 begin 137 i:=trunc(ln(deep[x]-deep[y])/ln(2)); 138 while deep[x]>deep[y] do 139 begin 140 while deep[x]-deep[y]>=1 << i do x:=fa[x][i]; 141 dec(i); 142 end; 143 end; 144 if x=y then exit(x); 145 i:=trunc(ln(n)/ln(2)); 146 while fa[x][0]<>fa[y][0] do 147 begin 148 while fa[x][i]<>fa[y][i] do 149 begin 150 x:=fa[x][i];y:=fa[y][i]; 151 end; 152 dec(i); 153 end; 154 exit(fa[x][0]); 155 end; 156 157 function query(p,l,r:longint):longint; 158 var mid,tem:longint; 159 begin 160 push(p); 161 if (tr[p].l=l)and(tr[p].r=r) then exit(tr[p].mx); 162 mid:=(tr[p].l+tr[p].r) >> 1; 163 if r<=mid then exit(query(p << 1,l,r)) else 164 if l>mid then exit(query(p << 1+1,l,r)) else 165 exit(max(query(p << 1,l,mid),query(p << 1+1,mid+1,r))); 166 end; 167 168 procedure dop(p,l,r:longint); 169 var mid,tem:longint; 170 begin 171 push(p); 172 if (tr[p].l=l)and(tr[p].r=r) then 173 begin 174 tem:=tr[p].mx;tr[p].mx:=-tr[p].mi;tr[p].mi:=-tem; 175 tr[p].op:=true; 176 exit; 177 end; 178 mid:=(tr[p].l+tr[p].r) >> 1; 179 if r<=mid then dop(p << 1,l,r) else 180 if l>mid then dop(p << 1+1,l,r) else 181 begin 182 dop(p << 1,l,mid); 183 dop(p << 1+1,mid+1,r); 184 end; 185 tr[p].mx:=max(tr[p << 1].mx,tr[p << 1+1].mx); 186 tr[p].mi:=min(tr[p << 1].mi,tr[p << 1+1].mi); 187 end; 188 189 function solve(x,y:longint):longint; 190 var mx:longint; 191 begin 192 mx:=-maxlongint; 193 while belong[x]<>belong[y] do 194 begin 195 mx:=max(mx,query(1,pos[belong[x]],pos[x])); 196 x:=fa[belong[x]][0]; 197 end; 198 if x<>y then mx:=max(mx,query(1,pos[y]+1,pos[x])); 199 exit(mx); 200 end; 201 202 procedure mend(x,y:longint); 203 begin 204 while belong[x]<>belong[y] do 205 begin 206 dop(1,pos[belong[x]],pos[x]); 207 x:=fa[belong[x]][0]; 208 end; 209 if x<>y then dop(1,pos[y]+1,pos[x]); 210 end; 211 212 begin 213 readln(test); 214 for tt:=1 to test do 215 begin 216 readln; 217 readln(n);j:=0; 218 fillchar(link,sizeof(link),0); 219 fillchar(next,sizeof(next),0); 220 fillchar(deep,sizeof(deep),0); 221 fillchar(fa,sizeof(fa),0); 222 for i:=1 to n-1 do 223 begin 224 readln(x,y,z); 225 add(x,y,z); 226 end; 227 deep[1]:=1;dfs1(1); 228 cnt:=0;dfs2(1,1); 229 build(1,1,n); 230 for i:=1 to n do insert(1,pos[i],pos[i],v[i]); 231 read(ch); 232 while ch<>'D' do 233 begin 234 if ch='Q' then 235 begin 236 readln(ch,ch,ch,ch,x,y); 237 t:=lca(x,y); 238 writeln(max(solve(x,t),solve(y,t))); 239 end else 240 if ch='N' then 241 begin 242 readln(ch,ch,ch,ch,ch,x,y); 243 t:=lca(x,y); 244 mend(x,t);mend(y,t); 245 end else 246 begin 247 readln(ch,ch,ch,ch,ch,x,y); 248 insert(1,pos[son[x]],pos[son[x]],y); 249 end; 250 read(ch); 251 end; 252 readln; 253 end; 254 end.