[BZOJ 2115 Wc2011 Xor]线性基
2017-12-08 18:58
399 查看
[BZOJ 2115 Wc2011 Xor]线性基
分类:Math
bitmask
线性基
1. 题目链接
[BZOJ 2115 Wc2011 Xor]2. 题意描述
一个边权非负整数的无向连通图,节点编号为1~n,求出一条从1号节点到n号节点的路径,使得路径上经过的边的权值XOR.数据范围:n≤50000,m≤100000,0≤边权≤1018
3. 解题思路
线性基解决的问题是:给定一个非负整数集合S,从中选出最小的子集T,使得对于集合S中的任意一个元素,都可以由集合T中若干元素XOR而成。
非常类似于线性代数里面的
最大线性无关组的定义。
然后就是要知道这样一个性质:图中所有环都是可以被异或的,因为我们可以从u出发到环的某一个点t,然后绕环一圈回到点t,然后再从t到u原路返回。那么此时的异或值就是环的异或值。
对于这个题目来说,可以在原图中dfs搞出一个生成树,并求出所有环的异或值。对所有环的向量组求一个线性基。那么答案就是生成树上从1到n的路径异或线性基中的若干向量的最大值。
那么做法就是从高位往低位贪心地选择加入或者不加入。
4. 实现代码
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii; typedef pair<ll, ll> pll; const int inf = 0x3f3f3f3f; const ll infl = 0x3f3f3f3f3f3f3f3fLL; template<typename T> inline void umax(T &a, T b) { a = max(a, b); } template<typename T> inline void umin(T &a, T b) { a = min(a, b); } const int MAXN = 50005; const int MAXM = 100005; typedef pair<int, ull> Edge; vector<Edge> G[MAXN]; int n, m; ull xpath[MAXN]; vector<ull> xorv; ull base[100]; bool used[MAXN]; void dfs(int u, int pre) { used[u] = true; for (int i = 0; i < G[u].size(); ++i) { Edge& e = G[u][i]; if (e.first == pre) continue; if (used[e.first]) { xorv.push_back(xpath[e.first] ^ xpath[u] ^ e.second); } else { xpath[e.first] = xpath[u] ^ e.second; dfs(e.first, u); } } } void Guass_base() { for (int i = 0; i <= 62; ++i) base[i] = 0; for (int i = 0; i < xorv.size(); ++i) { for (int j = 62; j >= 0; --j) { if (!(xorv[i] >> j & 1)) continue; if (!base[j]) { base[j] = xorv[i]; break; } xorv[i] ^= base[j]; } } } ull query(ull val) { for (int i = 62; i >= 0; --i) umax(val, val ^ base[i]); return val; } int main() { #ifdef ___LOCAL_WONZY___ freopen("input.txt", "r", stdin); #endif // ___LOCAL_WONZY___ int u, v; ull w; while (~scanf("%d %d", &n, &m)) { for (int i = 1; i <= n; ++i) { G[i].clear(); used[i] = false; } xorv.clear(); for (int i = 1; i <= m; ++i) { scanf("%d %d %llu", &u, &v, &w); G[u].push_back(Edge(v, w)); G[v].push_back(Edge(u, w)); } dfs(1, 0); sort(xorv.begin(), xorv.end()); xorv.erase(unique(xorv.begin(), xorv.end()), xorv.end()); Guass_base(); ull ans = query(xpath ); printf("%llu\n", ans); } #ifdef ___LOCAL_WONZY___ cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC * 1000 << "ms." << endl; #endif // ___LOCAL_WONZY___ return 0; }
相关文章推荐
- BZOJ 2115 WC2011 Xor 线性基+贪心
- BZOJ 2115: [Wc2011] Xor 线性基
- BZOJ 2115: [Wc2011] Xor [高斯消元XOR 线性基 图]
- BZOJ 2115 [Wc2011] Xor ——线性基
- BZOJ 2115: [Wc2011] Xor (dfs + gauss 线性基 异或最长路)
- BZOJ 2115: [Wc2011] Xor 线性基
- [BZOJ 2115][Wc2011] Xor:线性基
- [高斯消元 线性基] BZOJ 2115 [Wc2011] Xor
- 【BZOJ 2115】[Wc2011] Xor 线性基
- BZOJ 2115: [Wc2011] Xor DFS + 线性基
- bzoj 2115: [Wc2011] Xor(DFS+线性基)
- BZOJ 2115: [Wc2011] Xor
- Bzoj 2115: [Wc2011] Xor
- 2115: [Wc2011] Xor 线性基
- 【BZOJ】【P2115】【Wc2011】【Xor】【题解】【线性基】
- bzoj 2115: [Wc2011] Xor
- BZOJ 2115([Wc2011] Xor-线性基求法)
- bzoj 2115: [Wc2011] Xor【线性基+dfs】
- BZOJ 2115: [Wc2011] Xor
- 【bzoj 2115】: [Wc2011] Xor