bzoj 2115 Xor - 线性基 - 贪心
因为重复走一条边后,它的贡献会被消去。所以这条路径中有贡献的边可以看成是一条$1$到$n$的简单路径加上若干个环。
因此可以找任意一条路径,然后找出所有环扔进线性基跑出最大异或和。
但是找出所有环可能会T掉,但是仔细画图发现,并不需要找出所有环,例如:

在上图中,你并不需找出所有的环,只用找出1 - 3 - 4 - 2和3 - 5 - 6 - 4这两个环,它们异或后就能得到环1 - 3 - 5 - 6 - 4 - 2。
至于找这个环,可以用dfs生成树来找。当出现返祖边的时候就意味着找到了一个环。
然后可以记一个异或的前缀和,这样就可以$O(1)$算出环上的边权的异或和。
对于任意一条路径得到的异或和如果为$s$,那么我们只需要考虑线性基的每一位上,如果异或上它,能够使答案变大,就异或上它。
因为线性基不能保证最大的异或和由之前扔进去的所有数得到,所以必须这么贪一下心。
这样的正确性显然。
Code
/**
* bzoj
* Problem#2115
* Accepted
* Time: 740ms
* Memory: 7040k
*/
#include <bits/stdc++.h>
#ifndef WIN32
#define Auto "%lld"
#else
#define Auto "%I64d"
#endif using namespace std;
typedef bool boolean; #define ll long long typedef class LinearBasis {
public:
ll b[]; LinearBasis() { } void insert(ll x) {
for (int i = ; ~i; i--) {
if (x & (1ll << i)) x ^= b[i];
if (x & (1ll << i)) {
b[i] = x;
for (int j = i - ; ~j; j--)
if (b[i] & (1ll << j))
b[i] ^= b[j];
for (int j = i + ; j <= ; j++)
if (b[j] & (1ll << i))
b[j] ^= b[i];
break;
}
}
} ll getAns(ll ans) {
for (int i = ; i <= ; i++)
if ((ans ^ b[i]) > ans)
ans ^= b[i];
return ans;
}
}LinearBasis; typedef class Edge {
public:
int end, next;
ll w; Edge(int end = , int next = , ll w = ):end(end), next(next), w(w){ }
}Edge; typedef class MapManager {
public:
int ce;
int *h;
Edge* es; MapManager() { }
MapManager(int n, int m):ce() {
h = new int[(n + )];
es = new Edge[(m + )];
memset(h, , sizeof(int) * (n + ));
} void addEdge(int u, int v, ll w) {
es[++ce] = Edge(v, h[u], w);
h[u] = ce;
} Edge& operator [] (int p) {
return es[p];
}
}MapManager; int n, m;
ll *xs;
MapManager g;
LinearBasis lb;
boolean *vis; inline void init() {
scanf("%d%d", &n, &m);
xs = new ll[(n + )];
g = MapManager(n, m << );
vis = new boolean[(n + )];
ll w;
for (int i = , u, v; i <= m; i++) {
scanf("%d%d"Auto, &u, &v, &w);
g.addEdge(u, v, w);
g.addEdge(v, u, w);
}
} void dfs(int p) {
vis[p] = true;
for (int i = g.h[p]; i; i = g[i].next) {
int e = g[i].end;
if (vis[e])
lb.insert(xs[e] ^ xs[p] ^ g[i].w);
else {
xs[e] = xs[p] ^ g[i].w;
dfs(e);
}
}
} inline void solve() {
memset(vis, false, sizeof(boolean) * (n + ));
xs[] = ;
dfs();
printf(Auto"\n", lb.getAns(xs[n]));
} int main() {
init();
solve();
return ;
}
bzoj 2115 Xor - 线性基 - 贪心的更多相关文章
- BZOJ 2115 Xor(线性基)
题意:给定一个n<=50000个点m<=100000条边的无向联通图,每条边上有一个权值wi<=1e18.请你求一条从1到n的路径,使得路径上的边的异或和最大. 任意一条1到n的路径 ...
- BZOJ 4269: 再见Xor 线性基+贪心
Description 给定N个数,你可以在这些数中任意选一些数出来,每个数可以选任意多次,试求出你能选出的数的异或和的最大值和严格次大值. Input 第一行一个正整数N. 接下来一行N个非负整数. ...
- BZOJ 2460 & 洛谷 P4570 [BJWC2011]元素 (线性基 贪心)
题目链接: 洛谷 BZOJ 题意 给定 \(n\) 个矿石,每个矿石有编号和魔力值两种属性,选择一些矿石,使得魔力值最大且编号的异或和不为 0. 思路 线性基 贪心 根据矿石的魔力值从大到小排序. 线 ...
- [BZOJ 2115] Xor
Link:https://www.lydsy.com/JudgeOnline/problem.php?id=2115 Algorithm: 此题一看到是求异或和最大问题的,立即想到使用线性基解题 最终 ...
- BZOJ 2115 [Wc2011] Xor ——线性基
[题目分析] 显然,一个路径走过两边是不需要计算的,所以我么找到一条1-n的路径,然后向该异或值不断异或简单环即可. 但是找出所有简单环是相当复杂的,我们只需要dfs一遍,找出所有的环路即可,因为所有 ...
- BZOJ.2115.[WC2011]Xor(线性基)
题目链接 \(Description\) 给定一张无向带边权图(存在自环和重边).求一条1->n的路径,使得路径经过边的权值的Xor和最大.可重复经过点/边,且边权和计算多次. \(Soluti ...
- BZOJ 2115: [Wc2011] Xor 线性基 dfs
https://www.lydsy.com/JudgeOnline/problem.php?id=2115 每一条从1到n的道路都可以表示为一条从1到n的道路异或若干个环的异或值. 那么把全部的环丢到 ...
- BZOJ.2460.[BeiJing2011]元素(线性基 贪心)
题目链接 线性基:https://blog.csdn.net/qq_36056315/article/details/79819714. \(Description\) 求一组矿石,满足其下标异或和不 ...
- BZOJ 3105: [cqoi2013]新Nim游戏 [高斯消元XOR 线性基]
以后我也要用传送门! 题意:一些数,选择一个权值最大的异或和不为0的集合 终于有点明白线性基是什么了...等会再整理 求一个权值最大的线性无关子集 线性无关子集满足拟阵的性质,贪心选择权值最大的,用高 ...
随机推荐
- vue搭建环境并创建项目
1.>npm install @vue/cli -g 2.创建项目A a.>vue ui b.在弹出的管理界面创建项目 或 a.npm install -g @vue/cli-init b ...
- Mysql版本java问题(com.mysql.cj.jdbc.Driver和com.mysql.jdbc.Driver)
老版本com.mysql.jdbc.Driver已弃用 String url1 = "jabc:mysql://127.0.0.1:3306/test"; String url1 ...
- c++ 各种类型转换
1.int 2 string 法1:c++11里面的to_string #include <string> std::); //or auto s = std::to_string(); ...
- Java基础(basis)-----关键字this和super的作用
1.关键字this 可以用来修饰属性.方法.构造器:this理解为当前对象或当前正在创建的对象 局部变量与成员变量同名,成员变量被屏蔽,用"this.成员变量"的方式访问成员变量 ...
- js三目学习
<script> var n=1; n>1?document.write('大于1哦'):document.write('小于或等于1哦') //n=n>1?document. ...
- 两眼论&矩阵变现理论结合打造赚钱大模式
两眼论&矩阵变现理论结合打造赚钱大模式 围棋有一个基本规则,就是一块棋有两只真眼,就是活棋. 围棋没有复杂的规则,它最有趣的地方是没有太多的规则和限制,由此演变出了大千世界,所以古人云“棋如人 ...
- inux 驱动程序开发中输入子系统总共能产生哪些事件类型(EV_KEY,EV_ABS,EV_REL)
inux 驱动程序开发中, 输入子系统总共能产生哪些事件类型?,以及分别是什么意思?详见如下: Linux中输入设备的事件类型有EV_SYN 0x00 同步事件EV_KEY 0x01 按键事件,如KE ...
- Hadoop学习笔记之四:HDFS客户端
HDFS的客户端核心是DFSClient类,所有使用HDFS的客户端都会持有一个DFSClient对象,或通过持有一个DistributedFileSystem对象间接使用DFSClient: DFS ...
- 使用Wisdom RESTClient自动化测试REST API,如何取消对返回的body内容的校验?
使用Wisdom RESTClient V1.1 自动化测试API,默认是对返回HTTP状态码和body内容进行校验的. 如果您的API返回body内容是变化的,可以通过设置来取消对body内容的校验 ...
- nodejs安装淘宝npm镜像【cnpm】
安装完nodejs后[自带npm] 如果npm无法使用或需要FQ,可以先安装cnpm,然后使用cnpm install安装模块 安装全局cnpm npm install -g cnpm --regis ...