BZOJ2115: [Wc2011] Xor

$n \leq 5e4$,$m \leq 1e5$的边权无向图,问1到n的路径的边的异或和的最大值。

首先1到n的任意一条路径,可以由1到n的某一条路径异或上若干个环的异或和。

红色路径可以由黑色路径异或上两个环得到。

其次,我搞个树,然后一条非树边会和树边形成环,用这些只包含一条非树边的环异或起来可以得到所有的环。

哦它并不是要异或出所有的环而是要所有方案。两个环一起选也行。所以这样没问题。

然后丢进线性基找最大。

 1 //#include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 //#include<time.h>
 5 //#include<complex>
 6 //#include<set>
 7 //#include<queue>
 8 #include<algorithm>
 9 #include<stdlib.h>
10 using namespace std;
11 
12 #define LL long long
13 int qread()
14 {
15     char c; int s=0; while ((c=getchar())<'0' || c>'9');
16     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s;
17 }
18 
19 //Pay attention to '-' , LL and double of qread!!!!
20 
21 int n,m;
22 #define maxn 200011
23 struct Edge{int to,next; LL v;}edge[maxn<<1]; int first[maxn],le=2;
24 void in(int x,int y,LL v) {Edge &e=edge[le]; e.to=y; e.v=v; e.next=first[x]; first[x]=le++;}
25 void insert(int x,int y,LL v) {in(x,y,v); in(y,x,v);}
26 
27 struct JI
28 {
29     LL a[66]; int n;
30     void clear() {n=0; memset(a,0,sizeof(a));}
31     void insert(LL v)
32     {
33         for (int i=62;~i && v;i--) if ((v>>i)&1)
34         {
35             if (!a[i]) {a[i]=v; n++; break;}
36             v^=a[i];
37         }
38     }
39     LL qmax()
40     {
41         LL ans=0;
42         for (int i=62;~i;i--) ((ans^a[i])>ans) && (ans^=a[i]);
43         return ans;
44     }
45     void rebuild()
46     {
47         for (int i=62;~i;i--)
48             for (int j=i-1;~j;j--)
49                 if ((a[i]>>j)&1) a[i]^=a[j];
50     }
51     LL p[66]; int lp;
52     LL query(LL K)
53     {
54         lp=0; for (int i=0;i<=62;i++) if (a[i]) p[lp++]=a[i];
55         if (K>=(1ll<<lp)) return -1;
56         LL ans=0;
57         for (int i=lp-1;~i;i--) if ((K>>i)&1) ans^=p[i];
58         return ans;
59     }
60     LL qmax(LL v)
61     {
62         LL ans=v;
63         for (int i=62;~i;i--) (((ans>>i)&1)==0 && (ans^=a[i]));
64         return ans;
65     }
66 }ji;
67 
68 LL val[maxn];
69 void dfs(int x,int fa)
70 {
71     for (int i=first[x];i;i=edge[i].next)
72     {
73         Edge &e=edge[i]; if (e.to==fa) continue;
74         if (!~val[e.to]) {val[e.to]=val[x]^e.v; dfs(e.to,x);}
75         else ji.insert(e.v^val[e.to]^val[x]);
76     }
77 }
78 
79 int main()
80 {
81     n=qread(); m=qread();
82     LL V; for (int i=1,x,y;i<=m;i++) {x=qread(); y=qread(); scanf("%lld",&V); insert(x,y,V);}
83     
84     memset(val,-1,sizeof(val)); val[1]=0;
85     dfs(1,0);
86     printf("%lld\n",ji.qmax(val[n]));
87     return 0;
88 }
View Code

 

posted @ 2018-04-23 09:44  Blue233333  阅读(159)  评论(0编辑  收藏  举报