zoukankan      html  css  js  c++  java
  • 关于高斯消元解决xor问题的总结

    我觉得xor这东西特别神奇,最神奇的就是这个性质了 A xor B xor B=A

    这样就根本不用在意重复之类的问题了

    关于xor的问题大家可以去膜拜莫队的《高斯消元解XOR方程组》,里面写的很详细

    我来扯两道bzoj上的例题好了

    bzoj2115,求1-N最长xor路径,根据那个神奇的性质,我们先随便找一条1-n的路径作为标准路径

    任意一条1-N的路径都等价于标准路径和某些环的xor

    怎么找环?很简单,bfs下去,设d[x]表示1到x的一条路径xor值,如果到一条边x-->y时y已经访问过了,那么d[x] xor d[y] xor w[x,y]就是一个环

    然后这个问题就转变成了求一堆数中任意数xor最大的问题,这我们是通过求线性基然后按位贪心就可以了

     1 type node=record
     2        po,next:longint;
     3        num:int64;
     4      end;
     5 
     6 var f:array[0..64] of int64;
     7     d:array[0..50010] of int64;
     8     q,p:array[0..50010] of int64;
     9     a:array[0..500010] of int64;
    10     e:array[0..200010] of node;
    11     x,y,i,n,m,len,t:longint;
    12     ans,z:int64;
    13 
    14 procedure add(x,y:longint;z:int64);
    15   begin
    16     inc(len);
    17     e[len].po:=y;
    18     e[len].num:=z;
    19     e[len].next:=p[x];
    20     p[x]:=len;
    21   end;
    22 
    23 procedure bfs;
    24   var h,r,i,x,y:longint;
    25   begin
    26     fillchar(d,sizeof(d),255);
    27     d[1]:=0;
    28     h:=1; r:=1; q[1]:=1;
    29     while h<=r do
    30     begin
    31       x:=q[h];
    32       i:=p[x];
    33       while i<>0 do
    34       begin
    35         y:=e[i].po;
    36         if d[y]=-1 then
    37         begin
    38           d[y]:=d[x] xor e[i].num;
    39           inc(r);
    40           q[r]:=y;
    41         end
    42         else if d[y] xor d[x] xor e[i].num<>0 then  //找环
    43         begin
    44           inc(t);
    45           a[t]:=d[y] xor d[x] xor e[i].num;
    46         end;
    47         i:=e[i].next;
    48       end;
    49       inc(h);
    50     end;
    51   end;
    52 
    53 procedure gauss;
    54   var i,j:longint;
    55   begin
    56     for i:=1 to t do
    57       for j:=60 downto 0 do
    58         if a[i] and (int64(1) shl j)>0 then //求线性基
    59         begin
    60           if f[j]=0 then
    61           begin
    62             f[j]:=a[i];
    63             break;
    64           end
    65           else a[i]:=a[i] xor f[j];
    66         end;
    67 
    68     ans:=d[n];
    69     for i:=60 downto 0 do
    70       if ans and (int64(1) shl i)=0 then ans:=ans xor f[i];
    71   end;
    72 
    73 begin
    74   readln(n,m);
    75   for i:=1 to m do
    76   begin
    77     readln(x,y,z);
    78     add(x,y,z);
    79     add(y,x,z);
    80   end;
    81   bfs;
    82   gauss;
    83   writeln(ans);
    84 end.
    View Code

    bzoj2844

    一堆数xor能产生数的种类数就是2^线性基的秩

    并且每个数出现的次数是一样的(求证明)

    然后我们就可以做了,注意这里的线性基要用高斯消元求而不能用上题的方法

    因为要计算某个数出现在第几位,必须使线性基相互xor的数的大小满足二进制位的大小关系

    举个例子,比如线性基a,b,c并且a>b>c,如果取a,b xor,选取状况为110,这样选取xor的数一定要比011这样选大,我们称之为满足二进制大小关系(我自己口胡的名词)

     1 const mo=10086;
     2 
     3 var a,d:array[0..100010] of longint;
     4     f,b:array[0..40] of longint;
     5     k,p,i,j,n,ans,m,t:longint;
     6 
     7 procedure swap(var a,b:longint);
     8   var c:longint;
     9   begin
    10     c:=a;
    11     a:=b;
    12     b:=c;
    13   end;
    14 
    15 begin
    16   readln(n);
    17   for i:=1 to n do
    18     read(a[i]);
    19   d[0]:=1;
    20   for i:=1 to n do
    21     d[i]:=d[i-1]*2 mod mo;
    22 
    23   readln(m);
    24   k:=n;
    25   for i:=1 to n do
    26   begin
    27     for j:=i+1 to n do
    28       if a[i]<a[j] then swap(a[i],a[j]);
    29     if a[i]=0 then
    30     begin
    31       k:=i-1;
    32       break;
    33     end;
    34     for j:=30 downto 0 do
    35       if a[i] and (1 shl j)>0 then
    36       begin
    37         b[i]:=j;
    38         for p:=1 to n do
    39           if (p<>i) and (a[p] and (1 shl j)>0) then
    40             a[p]:=a[p] xor a[i];
    41         break;
    42       end;
    43   end;
    44   ans:=1;
    45   for i:=1 to k do
    46     if m and (1 shl b[i])>0 then
    47     begin
    48       m:=m xor a[i];
    49       ans:=(ans+d[k-i+n-k]) mod mo;
    50     end;
    51 
    52   writeln(ans);
    53 end.
    View Code
  • 相关阅读:
    C# 实现 Snowflake算法生成唯一性Id
    kafka可视化客户端工具(Kafka Tool)的基本使用(转)
    docker 安装kafka
    Model类代码生成器
    使用docker 部署rabbitmq 镜像
    Vue 增删改查 demo
    git 提交代码到库
    Android ble蓝牙问题
    mac 配置 ssh 到git (Could not resolve hostname github.com, Failed to connect to github.com port 443 Operation timed out)
    okhttp
  • 原文地址:https://www.cnblogs.com/phile/p/4490111.html
Copyright © 2011-2022 走看看