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.

 

转载于:https://www.cnblogs.com/qbwhtc/p/8419337.html

根据引用[1]中的代码,这段代码计算了一个数列的异或结果。首先,代码判断输入的数n是否为偶数,如果是偶数,则将n减1,并将结果赋给n。然后,代码计算了奇数的个数,如果奇数的个数为奇数,则将结果赋给ans,否则将0赋给ans。最后,如果n是偶数,则将ans与(n-1)进行异或运算,否则直接输出ans。这段代码的目的是计算数列的异或结果。[1] 根据引用[2]中的代码,这段代码也是计算了一个数列的异或结果。首先,代码判断输入的数n是否为偶数,如果是偶数,则将n减1,并将结果赋给n,并将even设置为true。然后,代码判断(n-1)右移1位后的结果是否为奇数,如果是奇数,则将1赋给ans,否则将0赋给ans。最后,如果n是偶数,则将ans与(n-1)进行异或运算,否则直接输出ans。这段代码的目的也是计算数列的异或结果。[2] 根据引用[3]中的代码,这段代码同样是计算了一个数列的异或结果。代码首先读取输入的数n,并计算n对4取余的结果赋给m。然后,根据m的值,分别计算不同情况下的ans的值。如果m为0,则将n赋给ans;如果m为1,则将1赋给ans;如果m为2,则将(n-1)赋给ans;如果m为3,则将0赋给ans。最后,输出ans。这段代码的目的也是计算数列的异或结果。[3] 综上所述,这些代码的目的都是计算数列的异或结果,只是实现的方式略有不同。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值