POJ3237Tree(树链剖分)
Posted myx12345
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ3237Tree(树链剖分)相关的知识,希望对你有一定的参考价值。
题意:在一棵N个节点,有边权的树上维护以下操作:
1:单边修改,将第X条边的边权修改成Y
2:区间取反,将点X与Y在树上路径中的所有边边权取反
3:区间询问最大值,询问X到Y树上路径中边权最大值
n<=10000 CAS<=20
思路:做了2天,改出来的一刻全身都萎掉了
边权转点权,点权就是它到父亲的边的边权,加一些反向标记
取反的标记TAG下传时不能直接赋值为-1,而是将原先的标记取反
多组数据时倍增数组,深度也需要清零
树链剖分不能取第一条边,需要+1
1 const oo=2000000000; 2 var t:array[1..100000]of record 3 min,max,tag:longint; 4 end; 5 f:array[0..30000,0..15]of longint; 6 head,vet,next,dep,tid,id,flag, 7 len,son,size,top,a,b,c,d,g,h:array[1..30000]of longint; 8 n,m,i,tot,x,y,k,v,cas,time,z,s,tmp,fuhao:longint; 9 ch:string; 10 11 function min(x,y:longint):longint; 12 begin 13 if x<y then exit(x); 14 exit(y); 15 end; 16 17 function max(x,y:longint):longint; 18 begin 19 if x>y then exit(x); 20 exit(y); 21 end; 22 23 procedure add(a,b,c:longint); 24 begin 25 inc(tot); 26 next[tot]:=head[a]; 27 vet[tot]:=b; 28 len[tot]:=c; 29 head[a]:=tot; 30 end; 31 32 procedure dfs(u:longint); 33 var e,v,i,t:longint; 34 begin 35 for i:=1 to 15 do 36 begin 37 if dep[u]<(1<<i) then break; 38 f[u,i]:=f[f[u,i-1],i-1]; 39 end; 40 e:=head[u]; flag[u]:=1; size[u]:=1; son[u]:=0; t:=0; 41 while e<>0 do 42 begin 43 v:=vet[e]; 44 if flag[v]=0 then 45 begin 46 dep[v]:=dep[u]+1; 47 f[v,0]:=u; 48 dfs(v); 49 size[u]:=size[u]+size[v]; 50 if size[v]>t then 51 begin 52 t:=size[v]; son[u]:=v; 53 end; 54 end; 55 e:=next[e]; 56 end; 57 end; 58 59 procedure swap(var x,y:longint); 60 var t:longint; 61 begin 62 t:=x; x:=y; y:=t; 63 end; 64 65 function lca(x,y:longint):longint; 66 var i,d:longint; 67 begin 68 if dep[x]<dep[y] then swap(x,y); 69 d:=dep[x]-dep[y]; 70 for i:=0 to 15 do 71 if d and (1<<i)>0 then x:=f[x,i]; 72 for i:=15 downto 0 do 73 if f[x,i]<>f[y,i] then 74 begin 75 x:=f[x,i]; y:=f[y,i]; 76 end; 77 if x=y then exit(x); 78 exit(f[x,0]); 79 end; 80 81 procedure pushdown(l,r,p:longint); 82 var mid,tmp,t1,t2:longint; 83 begin 84 tmp:=t[p].tag; 85 if (l=r)or(tmp=0) then exit; 86 t[p].tag:=0; 87 t1:=t[p<<1].min; t2:=t[p<<1].max; 88 t[p<<1].max:=-t1; t[p<<1].min:=-t2; 89 t1:=t[p<<1+1].min; t2:=t[p<<1+1].max; 90 t[p<<1+1].max:=-t1; t[p<<1+1].min:=-t2; 91 t[p<<1].tag:=-1-t[p<<1].tag; t[p<<1+1].tag:=-1-t[p<<1+1].tag; 92 93 end; 94 95 procedure pushup(p:longint); 96 begin 97 t[p].min:=min(t[p<<1].min,t[p<<1+1].min); 98 t[p].max:=max(t[p<<1].max,t[p<<1+1].max); 99 end; 100 101 procedure change(l,r,x,v,p:longint); 102 var mid:longint; 103 begin 104 pushdown(l,r,p); 105 if (l=x)and(r=x) then 106 begin 107 t[p].min:=v; t[p].max:=v; 108 // t[p].tag:=v; 109 exit; 110 end; 111 mid:=(l+r)>>1; 112 if x<=mid then change(l,mid,x,v,p<<1) 113 else change(mid+1,r,x,v,p<<1+1); 114 pushup(p); 115 end; 116 117 procedure dfs2(u,ance:longint); 118 var e,v:longint; 119 begin 120 flag[u]:=1; inc(time); tid[u]:=time; id[time]:=u; top[u]:=ance; 121 if son[u]>0 then dfs2(son[u],ance); 122 e:=head[u]; 123 while e<>0 do 124 begin 125 v:=vet[e]; 126 if flag[v]=0 then dfs2(v,v); 127 e:=next[e]; 128 end; 129 end; 130 131 procedure build(l,r,p:longint); 132 var mid:longint; 133 begin 134 if l=r then 135 begin 136 if h[id[l]]>oo then 137 begin 138 t[p].min:=oo; t[p].max:=-oo; 139 end 140 else begin t[p].min:=h[id[l]]; t[p].max:=h[id[l]]; end; 141 t[p].tag:=0; 142 exit; 143 end; 144 mid:=(l+r)>>1; 145 build(l,mid,p<<1); 146 build(mid+1,r,p<<1+1); 147 pushup(p); 148 end; 149 150 function query(l,r,x,y,p:longint):longint; 151 var mid,t1,t2:longint; 152 begin 153 pushdown(l,r,p); 154 if (l>=x)and(r<=y) then exit(t[p].max); 155 mid:=(l+r)>>1; query:=-oo; 156 if x<=mid then query:=max(query,query(l,mid,x,y,p<<1)); 157 if y>mid then query:=max(query,query(mid+1,r,x,y,p<<1+1)); 158 pushup(p); 159 end; 160 161 procedure negate(l,r,x,y,p:longint); 162 var mid,t1,t2:longint; 163 begin 164 pushdown(l,r,p); 165 if (l>=x)and(r<=y) then 166 begin 167 t1:=t[p].min; t2:=t[p].max; 168 t[p].min:=-t2; t[p].max:=-t1; 169 t[p].tag:=-1; 170 exit; 171 end; 172 mid:=(l+r)>>1; 173 if x<=mid then negate(l,mid,x,y,p<<1); 174 if y>mid then negate(mid+1,r,x,y,p<<1+1); 175 pushup(p); 176 end; 177 178 procedure ngt(x,y:longint); 179 var q:longint; 180 begin 181 q:=lca(x,y); 182 while top[x]<>top[q] do 183 begin 184 negate(1,n,tid[top[x]],tid[x],1); 185 x:=f[top[x],0]; 186 end; 187 if tid[q]+1<=tid[x] then negate(1,n,tid[q]+1,tid[x],1); 188 while top[y]<>top[q] do 189 begin 190 negate(1,n,tid[top[y]],tid[y],1); 191 y:=f[top[y],0]; 192 end; 193 if tid[q]+1<=tid[y] then negate(1,n,tid[q]+1,tid[y],1); 194 end; 195 196 function ask(x,y:longint):longint; 197 var q:longint; 198 begin 199 q:=lca(x,y); 200 ask:=-oo; 201 while top[x]<>top[q] do 202 begin 203 ask:=max(ask,query(1,n,tid[top[x]],tid[x],1)); 204 x:=f[top[x],0]; 205 end; 206 if tid[q]+1<=tid[x] then ask:=max(ask,query(1,n,tid[q]+1,tid[x],1)); 207 while top[y]<>top[q] do 208 begin 209 ask:=max(ask,query(1,n,tid[top[y]],tid[y],1)); 210 y:=f[top[y],0]; 211 end; 212 if tid[q]+1<=tid[y] then ask:=max(ask,query(1,n,tid[q]+1,tid[y],1)); 213 end; 214 215 begin 216 assign(input,‘tree.in‘); reset(input); 217 assign(output,‘poj3237.out‘); rewrite(output); 218 readln(cas); 219 for v:=1 to cas do 220 begin 221 readln(n); 222 fillchar(head,sizeof(head),0); tot:=0; time:=0; 223 fillchar(flag,sizeof(flag),0); 224 fillchar(d,sizeof(d),0); fillchar(g,sizeof(g),0); 225 fillchar(h,sizeof(h),$7f); fillchar(dep,sizeof(dep),0); 226 fillchar(f,sizeof(f),0); fillchar(tid,sizeof(tid),0); 227 fillchar(id,sizeof(id),0); 228 for i:=1 to n<<2 do 229 begin 230 t[i].min:=oo; t[i].max:=-oo; t[i].tag:=0; 231 end; 232 for i:=1 to n-1 do 233 begin 234 readln(a[i],b[i],c[i]); 235 add(a[i],b[i],c[i]); 236 add(b[i],a[i],c[i]); 237 end; 238 239 dfs(1); 240 fillchar(flag,sizeof(flag),0); 241 dfs2(1,1); 242 for i:=1 to n-1 do 243 begin 244 if dep[a[i]]<dep[b[i]] then tmp:=b[i] 245 else tmp:=a[i]; 246 d[i]:=tmp; g[tmp]:=i; h[tmp]:=c[i]; 247 end; 248 // h[1]:=0; d[n]:=1; g[1]:=n; 249 build(1,n,1); 250 while true do 251 begin 252 readln(ch); x:=0; y:=0; k:=length(ch); 253 if ch[1]=‘D‘ then break; s:=0; fuhao:=1; 254 for i:=1 to k do 255 begin 256 if ch[i]=‘ ‘ then begin inc(s); continue; end; 257 if (s=1)and(ch[i]<>‘ ‘) then x:=x*10+ord(ch[i])-ord(‘0‘); 258 if (s=2)and(ch[i]<>‘ ‘) then 259 begin 260 if ch[i]=‘-‘ then begin fuhao:=-1; continue; end 261 else y:=y*10+ord(ch[i])-ord(‘0‘); 262 end; 263 end; 264 if ch[1]=‘C‘ then change(1,n,tid[d[x]],fuhao*y,1); 265 if ch[1]=‘N‘ then ngt(x,y); 266 if ch[1]=‘Q‘ then 267 begin 268 writeln(ask(x,y)); 269 //writeln; 270 end; 271 end; 272 end; 273 close(input); 274 close(output); 275 end.
以上是关于POJ3237Tree(树链剖分)的主要内容,如果未能解决你的问题,请参考以下文章
POJ 3237 Tree (树链剖分 路径剖分 线段树的lazy标记)