BZOJ2115 [Wc2011] Xor

开始补冬令营期间做的题目啦~

好吧冬令营ydl大爷在上面讲图的树分解,我们一帮二子在下面讨论这道题,讨论了2个小时2333

进入正题。。。首先我们把图dfs一遍,记录下这颗dfs的生成树

我们会发现,所有边分成了两种:树边和回边,并且不存在两棵子树之间有边。

定义回边和其中的树边形成的环叫基本环,则基本环最多有m - n个

然后题解上有一句话"不难发现,答案是由1到n号点的一条树链和几个基本环形成的",我去脑补半天啊!!!因为是xor所以来回路径上的边都算了两次刚好抵消掉。

于是题解君就卖了个萌"高斯消元即可"。。。什么鬼。。。

(未完待续)

 1 /**************************************************************
 2     Problem: 2115
 3     User: rausen
 4     Language: C++
 5     Result: Accepted
 6     Time:328 ms
 7     Memory:11412 kb
 8 ****************************************************************/
 9
10 #include <cstdio>
11 #include <algorithm>
12
13 using namespace std;
14 typedef long long ll;
15 const int N = 50005;
16 const int M = N << 2;
17 const int Cnt = 100;
18 const int Maxlen = M * 30;
19
20 struct edge {
21     int next, to;
22     ll v;
23     edge() {}
24     edge(int _n, int _t, ll _v) : next(_n), to(_t), v(_v) {}
25 } e[M];
26
27 int n, m, cnt;
28 int first[N];
29 ll f[N], Ans;
30 ll ans[Cnt], from[Cnt];
31 bool vis[N];
32
33 char buf[Maxlen], *c = buf;
34 int Len;
35
36 inline ll read() {
37     ll x = 0;
38     while (*c < ‘0‘ || ‘9‘ < *c) ++c;
39     while (‘0‘ <= *c && *c <= ‘9‘)
40         x = x * 10 + *c - ‘0‘, ++c;
41     return x;
42 }
43
44 #define y e[x].to
45 void dfs(int p) {
46     int x;
47     vis[p] = 1;
48     for (x = first[p]; x; x = e[x].next)
49         if (!vis[y]) {
50             f[y] = f[p] ^ e[x].v;
51             dfs(y);
52         }
53 }
54 #undef y
55
56 void work(int x, int y, ll v) {
57     int i;
58     v = v ^ f[x] ^ f[y];
59     for (i = 1; i <= cnt && v; ++i)
60         if (v & ans[i]) v ^= from[i];
61     if (!v) return;
62     ++cnt, ans[cnt] = 1, from[cnt] = v;
63     while ((ans[cnt] << 1) <= v) ans[cnt] <<= 1;
64     for (i = cnt; i > 1; --i)
65         if (ans[i] > ans[i - 1])
66             swap(ans[i], ans[i - 1]), swap(from[i], from[i - 1]);
67 }
68
69 int main() {
70     Len = fread(c, 1, Maxlen, stdin);
71     buf[Len] = ‘\0‘;
72     int i, x, y;
73     ll z;
74     n = read(), m = read();
75     for (i = 1; i <= m; ++i) {
76         x = read(), y = read(), z = read();
77         e[i] = edge(first[x], y, z), first[x] = i;
78         e[i + m] = edge(first[y], x, z), first[y] = i + m;
79     }
80     dfs(1);
81     for (i = 1; i <= m; ++i)
82         work(e[i].to, e[i + m].to, e[i].v);
83     Ans = f[n];
84     for (i = 1; i <= cnt; ++i)
85         if (!(Ans & ans[i])) Ans ^= from[i];
86     printf("%lld\n", Ans);
87     return 0;
88 }

时间: 2024-10-22 09:27:04

BZOJ2115 [Wc2011] Xor的相关文章

BZOJ2115 WC2011 Xor DFS+高斯消元

题意:给定一张无向图,求1到N异或和最大的路径,允许重复经过. 题解:首先跑出1到N的一条路径,答案就是在这条路径上不断加环.首先用DFS处理出所有基环的异或和(其他环一定由基环构成,重复部分异或之后就会消掉),然后就是从一堆数里选任意个数使得异或和最小了,怎么做可以去看莫涛的课件(同解01异或方程),这里我简单介绍一下. 通过高斯消元,我们对原来的数进行操作,使得所有原来的数都可以用操作之后的数来组合而成(这玩意貌似叫线性基啊).具体做法就是从高到低暴力枚举每一位i,找到一个第i位为1的数j,

bzoj2115 [Wc2011] Xor——高斯消元 &amp; 异或线性基

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2115 异或两次同一段路径的权值,就相当于没有走这段路径: 由此可以得到启发,对于不同的走法,也许只需要找出一些东西,就可以把所有的走法用它们来异或表示出来: 再关注图上的环路,因为从 1 到 n 的不同路径也可以看作是经由 1 和 n 连接的环路,路径上也可能有环路: 发现对于环路的不同走法,就是把路与环的权值异或求最优值,重叠的部分异或了两次相当于不走: 于是问题转化为找出图上的所有环(

bzoj 2115: [Wc2011] Xor xor高斯消元

2115: [Wc2011] Xor Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 797  Solved: 375[Submit][Status] Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di的无向边. 图中可能有重边或自环. Output 仅包含一个整数,表示最大的XOR和(十进制结

【BZOJ 2115】 [Wc2011] Xor

2115: [Wc2011] Xor Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 962  Solved: 441 [Submit][Status] Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di的无向边. 图中可能有重边或自环. Output 仅包含一个整数,表示最大的XOR和(十进

【BZOJ-2115】Xor 线性基 + DFS

2115: [Wc2011] Xor Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 2142  Solved: 893[Submit][Status][Discuss] Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di的无向边. 图中可能有重边或自环. Output 仅包含一个整数,表示最大

2115: [Wc2011] Xor (线性基+dfs)

2115: [Wc2011] Xor Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 5714  Solved: 2420 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2115 Description: Input: 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di

【bzoj2115】[Wc2011] Xor【高斯消元】

题目大意:给出一个无向有权图,找出一条从1到n的路径,使得路径上权值的异或和最大,路径可以重复走 Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di的无向边. 图中可能有重边或自环. Output 仅包含一个整数,表示最大的XOR和(十进制结果) . Sample Input 5 71 2 21 3 22 4 12 5 14 5 35 3 44 3 2 Sample

[bzoj2115] [洛谷P4151] [Wc2011] Xor

Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di的无向边. 图中可能有重边或自环. Output 仅包含一个整数,表示最大的XOR和(十进制结果),注意输出后加换行回车. Sample Input 5 7 1 2 2 1 3 2 2 4 1 2 5 1 4 5 3 5 3 4 4 3 2 Sample Output 6 HINT 想法 手动

BZOJ2115:[WC2011]Xor——题解

https://www.lydsy.com/JudgeOnline/problem.php?id=2115 https://www.luogu.org/problemnew/show/P4151 这道题当年还是新题,现在都成线性基套路题了. 参考:https://blog.sengxian.com/algorithms/linear-basis 一个1~n路径值可以拆成一条1~n的路径值^几个环(因为去到环和回来的路的值被异或回去了). 于是就变成了处理出所有环的异或值和所有1~n的无环路的异或