博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线性基
阅读量:7101 次
发布时间:2019-06-28

本文共 3240 字,大约阅读时间需要 10 分钟。

整理一下线性基的题

HDU 5544

题意

给一个有边权的无向图,找一条闭合路径,使路径上权值异或和最大

题解

Hint1 如果这个图是一棵树?

Hint2 环之间相互独立?

对图进行一遍DFS,把所有找到的环插入线性基,再求最大值即可

#include 
#include
using namespace std;#define N 500010typedef long long LL;vector< pair
> G[N];int T, n, m, u, v, cas, vis[N];LL xorsum[N], p[N], w;void insert(LL x) { for (int i = 62; i >= 0; i --) if ((x >> i) & 1) { if ( p[i] ) { x ^= p[i]; } else { p[i] = x; break; } }}void dfs(int u) { vis[u] = 1; for (int i=0;i
= 0; i --) if ((p[i] ^ ans) > ans) ans ^= p[i]; printf("Case #%d: %lld\n", ++ cas, ans); }}

WannaFly 挑战赛1 E

题意

给定一个无向简单图(即无重边无自环). 每条边都有一个权值. 这个图的一个鸽, 指的是将它的点集划分为两个不重不漏的集合S和T. 这个鸽的权值, 是所有两个端点分别属于S和T的边的权值的异或和(即, S内部的边和T内部的边都不算). 现在问这个图的鸽的所有可能权值的和是多少. 由于这个数很大, 只需要输出前9位, 不足9位则全部输出.

题解

每个划分方式对应一个二分图。辣么我们枚举所有的二分图。

把每个点的点权设为:与该点先连的边的权值异或和。然后把这些点权插入线性基即可。
考虑每个点取还是不取的同时,二分图就被枚举了。

#include 
using namespace std;typedef long long LL;#define N 5000000int n, m, u, v;LL w, a[N], p[N];void ins(LL x) { for (int i = 40; i >= 0; i --) if ((x >> i) & 1){ if (!p[i]) { p[i] = x; break; } else { x ^= p[i]; } }}int main() { scanf("%d %d", &n, &m); for (int i = 1; i <= m; i ++) { scanf("%d %d %lld", &u, &v, &w); a[u] ^= w; a[v] ^= w; } for (int i = 1; i <= n; i ++) { ins(a[i]); } LL ans = 0, cnt = 0; for (int i = 0; i <= 40; i ++) if (p[i]) cnt ++; for (int i = 0; i <= 40; i ++) for (int j = 0; j <= i-1; j ++) p[i] ^= (p[i] & p[j]); for (int i = 0; i <= 40; i ++) { ans = ans + p[i] * (1LL << (cnt - 1)); } while (ans >= 1000000000) ans /= 10; printf("%lld\n", ans);}

高斯消元版本

#include 
#include
using namespace std;typedef long long LL;const int N = 100000+10;int n, m, a[N], u, v, w;//0-indexint bit[32];int main() { scanf("%d %d", &n, &m); for (int i=1;i<=m;i++) { scanf("%d %d %d", &u, &v, &w); a[--u] ^= w, a[--v] ^= w; } int q = 0; for (int j = 31; j >= 0; j --) for (int i = q; i < n; i ++) if ((a[i] >> j) & 1) { swap(a[i], a[q]); bit[q ++] = (1 << j); for (int k = q; k < n; k ++) { if (a[k] & bit[q-1]) a[k] ^= a[q-1]; } } for (int i = q-1; i >= 0; i --) for (int j = i-1; j >= 0; j --) a[j] ^= (a[j]&a[i]); LL ans = 0; for (int i = 0; i < q; ++i) { ans += (1LL << (q - 1)) * a[i]; } while (ans > 999999999) { ans /= 10; } printf("%lld\n", ans);}

TopCoder - 12197

高斯消元后贪心凑最大。注意到:若两向量组张成的空间相同,则为等价。

LL maxSum(vector
a) { n = a.size(); int q = 0; for (int j=60;j>=0;j--) for (int i=q;i
>j)&1) { swap(a[i], a[q]); bit[q ++] = (1LL<
=0;i--) for (int j=i-1;j>=0;j--) if (a[j] & bit[i]) a[j] ^= a[i]; for (int i=1;i

转载于:https://www.cnblogs.com/RUSH-D-CAT/p/7675154.html

你可能感兴趣的文章
006-unity3d GUI初识、贴图、自定义鼠标指针
查看>>
Set replication in Hadoop
查看>>
Linux - 进程与内存查看
查看>>
【边做项目边学Android】手机安全卫士05_2:程序主界面,为每一个条目加入事件...
查看>>
Linux下Shell脚本替换换行符(转)
查看>>
C#集合类型
查看>>
jsp:xpath - xml
查看>>
CentOS7图形界面与命令行界面切换
查看>>
pthread_cleanup_push
查看>>
mysql 手册关于修改列字符编码的一个bug
查看>>
高性能爬虫——asynicio模块
查看>>
Docker容器的数据卷(data volume),数据卷容器,数据卷的备份和还原。
查看>>
win10 字体渲染优化 色彩调整
查看>>
分享基于MemoryCache(内存缓存)的缓存工具类,C# B/S 、C/S项目均可以使用!
查看>>
VC++:ActiveX Test Container
查看>>
iOS知识点汇总
查看>>
butterknife用法总结
查看>>
Win8 Metro(C#)数字图像处理--2.55OSTU法图像二值化
查看>>
ReactiveCocoa 中 RACSignal 所有变换操作底层实现分析(上)
查看>>
Service Fabric本地开发部署修改数据目录
查看>>