[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 v Change the weight of the ith edge to v
NEGATE a b Negate the weight of every edge on the path from a to b
QUERY a b Find 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.
原文地址:https://www.cnblogs.com/mjy0724/p/4417212.html