博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
「线性基」学习笔记and乱口胡总结
阅读量:4683 次
发布时间:2019-06-09

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

还以为是什么非常高大上的东西花了1h不到就学好了

线性基

线性基可以在\(O(nlogx)\)的时间内计算出\(n\)个数的最大异或和(不需要相邻)。

上述中\(x\)表示的最大的数。

如何实现

定义\(p[i]\)表示在二进制下从最高位开始第一个出现\(1\)的数。

当前我们将一个数插入线性基中。
如果\(x\)的最高位的\(1\)还没有被插入过,那么就在这一位上插入\(x\)
如果当前这一位被插入过,那么就异或上这一位上的数。
查询操作:从最高位上开始贪心。
如果异或这一位上的数可以让答案更大,那么就异或,否则就异或。

贪心验证

因为我们从高位往低位贪心,所以不需要考虑低位上的数会让高位上的数变小的情况。

介于我们在插入的时候都是无法匹配的时候,异或上这一位上的数,那么就保证了我们的这个数能够达到自己能用的最大贡献。

代码

#include 
using namespace std;const int BIT = 63;const int N = 52;typedef long long ll;ll a[N], p[BIT + 2];int n; void ins(ll x) { for (int i = BIT; ~i; i --) { if ((x >> i) == 0) continue; if (!p[i]) { p[i] = x; break; } x ^= p[i]; }}int main() { cin >> n; for (int i = 1; i <= n; i ++) cin >> a[i]; for (int i = 1; i <= n; i ++) ins(a[i]); for (int i = 0; i <= BIT; i ++) cout << i << " " << p[i] << endl; cout << endl; ll ans = 0; for (int i = BIT; ~i; i --) if ((ans ^ p[i]) > ans) ans ^= p[i]; cout << ans << endl; return 0;}

转载于:https://www.cnblogs.com/chhokmah/p/10748282.html

你可能感兴趣的文章
linux配置java环境变量(详细)
查看>>
刚毕业的小鲜肉
查看>>
定义列属性:null,default,PK,auto_increment
查看>>
zookeeper笔记
查看>>
VMware装CentOS注意事项 IP
查看>>
(二)apache atlas配置和运行
查看>>
内部类之非静态内部类补充
查看>>
用户画像展示
查看>>
LeetCode题解-----Sliding Window Maximum
查看>>
【USACO 5.4.1】Canada Tour
查看>>
(转)SharePoint对象模式获取“用户或用户组”栏的值
查看>>
pyqt pyinstaller使用说明
查看>>
C#中StreamReader读取中文出现乱码
查看>>
引用堆中的对象
查看>>
用CSS开启硬件加速来提高网站性能(转)
查看>>
使用BufferedReader的时候出现的问题
查看>>
加快页面加载速度的方法
查看>>
Oozie协作框架
查看>>
linux安装图形界面
查看>>
Android广播发送失败
查看>>