Luogu P2420 让我们异或吧

用LCA可做~

基本上可以算是LCA模板题了,套一顿LCA模板即可实现~

注:以下floor[i]为第i个点的层数,fa[i,j]为i节点向上的第2^j个节点的编号,f[i,j]为i节点向上跑2^j条边的答案(也就是异或值)。

P.S.:话说为什么最近Pascal的题解越来越少了qwq……


pascal代码如下:

var n,m,i,j,k,x,y,z,ans:longint;
en,dis,find,next,last,floor:array[0..200000]of longint;
f,fa:array[0..100000,0..17]of longint;
b:array[1..100000]of boolean;
procedure build(x,y:longint);
begin
  inc(k);
  next[k]:=last[x];
  last[x]:=k;
  en[k]:=y;
  dis[k]:=z;
end;
begin
  readln(n);
  for m:=1 to n-1 do//邻接表存边(因为无向,所以存两遍,注意数组也要开大一倍)
  begin
    readln(x,y,z);
    build(x,y);
    build(y,x);
  end;
  find[1]:=1;
  x:=1;
  y:=1;
  b[1]:=true;
  floor[1]:=1;
  while x<=y do//BFS建树
  begin
    i:=last[find[x]];
    while i>0 do
    begin
      if not b[en[i]] then
      begin
        inc(y);
        find[y]:=en[i];
        fa[en[i],0]:=find[x];
        f[en[i],0]:=dis[i];
        b[en[i]]:=true;
        floor[en[i]]:=floor[find[x]]+1;
      end;
      i:=next[i];
    end;
    inc(x);
  end;
  for j:=1 to 17 do//处理ST表
  for i:=1 to n do
  begin
    fa[i,j]:=fa[fa[i,j-1],j-1];
    f[i,j]:=f[i,j-1] xor f[fa[i,j-1],j-1];
  end;
  readln(m);
  for i:=1 to m do//LCA模板(倍增)(注意答案是在求异或值就行了qwq)
  begin
    readln(x,y);
    if floor[x]<floor[y] then
    begin
      z:=x;
      x:=y;
      y:=z;
    end;
    ans:=0;
    if floor[x]>floor[y] then
    for j:=17 downto 0 do
    if floor[fa[x,j]]>=floor[y] then
    begin
      ans:=ans xor f[x,j];
      x:=fa[x,j];
    end;
    if x=y then
    begin
      writeln(ans);
      continue;
    end;
    for j:=17 downto 0 do
    if fa[x,j]<>fa[y,j] then
    begin
      ans:=ans xor f[x,j] xor f[y,j];
      x:=fa[x,j];
      y:=fa[y,j];
    end;
    writeln(ans xor f[x,0] xor f[y,0]);
  end;
end.

 

posted @ 2018-02-05 20:32  qbwhtc  阅读(117)  评论(0编辑  收藏  举报