给定一棵有n个节点的无根树和m个操作,操作有2类:
1、将节点a到节点b路径上所有点都染成颜色c;
2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由3段组成:“11”、“222”和“1”。
请你写一个程序依次完成这m个操作。
与上一题差别不大,主要就是solve过程要根据左端点和右端点的颜色处理合并时候的情况
线段树的每个节点要记录颜色段数|最左边的颜色|最右边的颜色
同时往下传的时候标记要做好(之前那道题是单点修改所以不用考虑下传
因为这个昨晚调了一个晚上无果...果然是早上头脑清醒的多 一下子就改好了...
program bzoj2243; const maxn=1000010;maxm=2000010; var ter,next:array[-1..maxm]of longint; link,pos,deep,size,belong,v:array[-1..maxn]of longint; fa:array[-1..maxn,-1..20]of longint; cnt,n,m,i,j,x,y,z,t:longint; ch:char; tr:array[-1..5*maxn]of record l,r,lc,rc,cover:longint;wait:boolean;end; procedure add(x,y:longint); begin inc(j);ter[j]:=y;next[j]:=link[x];link[x]:=j; inc(j);ter[j]:=x;next[j]:=link[y];link[y]:=j; end; procedure dfs1(p:longint); var i,j:longint; begin size[p]:=1; for i:=1 to 17 do begin if deep[p]<=1 << i then break; fa[p][i]:=fa[fa[p][i-1]][i-1]; end; j:=link[p]; while j<>0 do begin if deep[ter[j]]=0 then begin deep[ter[j]]:=deep[p]+1; fa[ter[j]][0]:=p; dfs1(ter[j]); inc(size[p],size[ter[j]]); end; j:=next[j]; end; end; procedure dfs2(p,chain:longint); var j,k:longint; begin inc(cnt);pos[p]:=cnt;belong[p]:=chain; k:=0; j:=link[p]; while j<>0 do begin if deep[ter[j]]>deep[p] then if size[ter[j]]>size[k] then k:=ter[j]; j:=next[j]; end; if k=0 then exit; dfs2(k,chain); j:=link[p]; while j<>0 do begin if (deep[ter[j]]>deep[p])and(k<>ter[j]) then dfs2(ter[j],ter[j]); j:=next[j]; end; end; procedure build(p,l,r:longint); var mid:longint; begin tr[p].l:=l;tr[p].r:=r;tr[p].cover:=1;tr[p].lc:=-1;tr[p].rc:=-1; if l=r then exit; mid:=(l+r) >> 1; build(p << 1,l,mid); build(p << 1+1,mid+1,r); end; procedure insert(p,l,r,x:longint); var mid:longint; begin if (tr[p].l=l)and(tr[p].r=r) then begin tr[p].cover:=1;tr[p].lc:=x;tr[p].rc:=x;tr[p].wait:=true; exit; end; mid:=(tr[p].l+tr[p].r) >> 1; if tr[p].wait then begin tr[p << 1].cover:=1;tr[p << 1].lc:=tr[p].lc;tr[p << 1].rc:=tr[p].rc; tr[p << 1+1].cover:=1;tr[p << 1+1].lc:=tr[p].lc;tr[p << 1+1].rc:=tr[p].rc; tr[p].wait:=false; tr[p << 1].wait:=true;tr[p << 1+1].wait:=true; end; if r<=mid then insert(p << 1,l,r,x) else if l>mid then insert(p << 1+1,l,r,x) else begin insert(p << 1,l,mid,x); insert(p << 1+1,mid+1,r,x); end; tr[p].cover:=tr[p << 1].cover+tr[p << 1+1].cover; if tr[p << 1].rc=tr[p << 1+1].lc then dec(tr[p].cover); tr[p].lc:=tr[p << 1].lc;tr[p].rc:=tr[p << 1+1].rc; end; function lca(x,y:longint):longint; var tem,i:longint; begin if deep[x]<deep[y] then begin tem:=x;x:=y;y:=tem; end; if deep[x]>deep[y] then begin i:=trunc(ln(deep[x]-deep[y])/ln(2)); while deep[x]<>deep[y] do begin while (deep[x]-deep[y]>=1 << i) do x:=fa[x][i]; dec(i); end; end; if x=y then exit(x); i:=trunc(ln(n)/ln(2)); while fa[x][0]<>fa[y][0] do begin while (fa[x][i]<>fa[y][i]) do begin x:=fa[x,i];y:=fa[y][i]; end; dec(i); end; exit(fa[x,0]); end; procedure query(p,l,r:longint;var lc,rc,ave:longint); var mid,ll,rr,x,tem:longint; begin if (tr[p].l=l)and(tr[p].r=r) then begin lc:=tr[p].lc;rc:=tr[p].rc; ave:=tr[p].cover; exit; end; mid:=(tr[p].l+tr[p].r) >> 1; if tr[p].wait then begin tr[p << 1].cover:=1;tr[p << 1].lc:=tr[p].lc;tr[p << 1].rc:=tr[p].rc; tr[p << 1+1].cover:=1;tr[p << 1+1].lc:=tr[p].lc;tr[p << 1+1].rc:=tr[p].rc; tr[p].wait:=false; tr[p << 1].wait:=true;tr[p << 1+1].wait:=true; end; if r<=mid then query(p << 1,l,r,lc,rc,ave) else if l>mid then query(p << 1+1,l,r,lc,rc,ave) else begin query(p << 1,l,mid,lc,ll,ave); query(p << 1+1,mid+1,r,rr,rc,tem); inc(ave,tem); if ll=rr then dec(ave); end; end; function solve(x,y:longint):longint; var r,sum,lc,rc,tem:longint; begin r:=-1;sum:=0; while belong[x]<>belong[y] do begin query(1,pos[belong[x]],pos[x],lc,rc,tem); inc(sum,tem); if rc=r then dec(sum); r:=lc; x:=fa[belong[x]][0]; end; query(1,pos[y],pos[x],lc,rc,tem); inc(sum,tem); if rc=r then dec(sum); exit(sum); end; procedure mend(x,y,z:longint); begin while belong[x]<>belong[y] do begin insert(1,pos[belong[x]],pos[x],z); x:=fa[belong[x]][0]; end; insert(1,pos[y],pos[x],z); end; begin readln(n,m); for i:=1 to n do read(v[i]);readln; j:=0; for i:=1 to n-1 do begin readln(x,y); add(x,y); end; deep[1]:=1; dfs1(1); cnt:=0;dfs2(1,1); build(1,1,n); for i:=1 to n do insert(1,pos[i],pos[i],v[i]); for i:=1 to m do begin read(ch); if ch=‘C‘ then begin readln(x,y,z); t:=lca(x,y); mend(x,t,z);mend(y,t,z); end else begin readln(x,y); z:=lca(x,y); writeln(solve(x,z)+solve(y,z)-1); end; end; end.