[高斯消元与线性基]
来源:互联网 发布:苹果版手机淘宝 编辑:程序博客网 时间:2024/05/01 09:58
[BZOJ 2115][WC 2011]Xor
题意
- 给定一个n个点m条边的无向图,求一条路径使得路径的异或和最大
分析
- 随便搞出一条路径
- 考虑环,路径^环=路径,相当于我们从环的另一侧走过去,考虑两条路径,路径^路径=环
- 然后找到图中所有的环分别求xor,最后判定取哪些环能使答案最大。
- 进行高斯消元,用拟阵证明取线性基的正确性
Code
#include <bits/stdc++.h>using namespace std;#define N 50010#define M 200010typedef long long ll;struct Edge{ int to, next; ll w;}edge[M];int cnt, h[N], n, m;void add(int u, int v, ll w){ cnt ++; edge[cnt].to = v; edge[cnt].w = w; edge[cnt].next = h[u]; h[u] = cnt; swap(u, v); cnt ++; edge[cnt].to = v; edge[cnt].w = w; edge[cnt].next = h[u]; h[u] = cnt;}ll d[N], a[M], num;bool vis[N];void dfs(int x){ vis[x] = 1; for(int i = h[x]; i; i = edge[i].next){ int y = edge[i].to; if(!vis[y]) d[y] = d[x] ^ edge[i].w, dfs(y); else a[++ num] = d[y] ^ d[x] ^ edge[i].w; }}int gauss(){ int k = 1; for(int p = 63; p >= 0; p --){ int t = 0; for(int i = k; i <= num; i ++) if(a[i] >> p & 1){t = i; break;} if(t){ swap(a[t], a[k]); for(int i = 1; i <= num; i ++) if(i != k && (a[i] >> p & 1)) a[i] ^= a[k]; k ++; } } return k - 1;}int main(){ scanf("%d%d", &n, &m); int u, v; ll w; for(int i = 1; i <= m; i ++){ scanf("%d%d%lld", &u, &v, &w); add(u, v, w); } dfs(1); int cnt = gauss(); ll ans = d[n]; for(int i = 1; i <= cnt; i ++) if((ans ^ a[i]) > ans) ans ^= a[i]; printf("%lld\n", ans); return 0;}
[BZOJ 2460][BeiJing2011]元素
题意:
- 给定一些元素,每个元素有两个值a和b,现在需要选出一些元素,在不存在a值异或和为0的子集的情况下使b之和最大
分析
- 贪心(拟阵)+线性基
#include <bits/stdc++.h>#define maxn 1010using namespace std;typedef long long ll;struct Point{ ll a; int b; bool operator<(const Point& k)const{ return b > k.b; }}p[maxn];int n;ll ans, base[maxn];int main(){ scanf("%d", &n); for(int i = 1; i <= n; i ++) scanf("%lld%d", &p[i].a, &p[i].b); sort(p+1, p+1+n); for(int i = 1; i <= n; i ++){ for(int j = 63; ~j; j --){ if(p[i].a >> j & 1){ if(!base[j]){ base[j] = p[i].a; break; } p[i].a ^= base[j]; } } if(p[i].a)ans += p[i].b; } printf("%lld\n", ans); return 0;}
[BZOJ 4004][JLOI2015]装备购买
题意:
- 有一个人买一些装备,要求线性无关,求买装备最多而且花费最少
分析:
- 拟阵证明贪心的正确性
- 用高斯消元维护线性基
#include <bits/stdc++.h>#define maxn 510using namespace std;typedef long long ll;//const int mod = 998224353;const int mod = 1e9 + 7;struct Node{ int a[maxn], c; bool operator<(const Node& k)const{return c < k.c;}}p[maxn], bases[maxn];bool bases_flag[maxn];int n, m;ll power_mod(ll a, ll b, ll mod){ ll ret = 1; while(b){ if(b & 1)ret = ret * a % mod; b >>= 1; a = a * a % mod; }return ret;}void Gauss(Node& a, const Node& b, int o){ //t = a.a[o] / b.b[o] ll t = mod - a.a[o] * power_mod(b.a[o], mod-2, mod) % mod; for(int i = o; i <= m; i ++) a.a[i] =(a.a[i] + b.a[i] * t) % mod;}bool Insert(int pos){ for(int i = 1; i <= m; i ++){ if(p[pos].a[i]){ if(!bases_flag[i]){ bases[i] = p[pos]; bases_flag[i] = true; return true; } Gauss(p[pos], bases[i], i); } } return false;}int main(){ scanf("%d%d", &n, &m); for(int i = 1; i <= n; i ++) for(int j = 1; j <= m; j ++) scanf("%d", &p[i].a[j]); for(int i = 1; i <= n; i ++) scanf("%d", &p[i].c); sort(p+1, p+1+n); long long ans = 0; int cnt = 0; for(int i = 1; i <= n; i ++) if(Insert(i))ans += p[i].c, cnt ++; printf("%d %lld\n", cnt, ans); return 0;}
0 1
- [高斯消元与线性基]
- 高斯消元&线性基模板
- 关于线性基的学习与理解
- 关于线性基的学习与理解
- BZOJ 2844 高斯消元 线性基
- BZOJ 3105 线性基 高斯消元
- 高斯消元&&线性基 算法小结
- 线性电源与开关电源
- 对称性与线性相位
- 对称性与线性相位
- 开关电源与线性电源
- 【线性空间】与【线性变换】
- 线性与二次判别分析
- 线性与非线性
- 线性代数(六) : 线性相关与线性无关
- 线性回归与局部加权线性回归
- 线性可分与线性不可分
- 线性可分 与线性不可分
- C#设置子窗体在主窗体中居中显示解决方案
- Didn't find class “android.support.v7.internal.widget.TintManager” on path
- java_juc_同步工具集
- CMarkup 入门(增删改查)
- HBase数据备份
- [高斯消元与线性基]
- MySQL 5.7 root登录问题
- VM的几种网络连接方式
- Android设置textview的字体之间的间距
- IIC总线协议总结
- js中如何定义常量
- 更换CentOS的下载源为阿里源
- 计算机视觉中的ICP算法
- 从开闭原则,讲讲初级的代码设计