线性基

线性基

用处:有 n 个数,求这些数选一些出来异或,能得到的最大值是多少

线性基一般指的是异或线性基。它满足如下这些性质

  • 原序列中的任何一个数都可以线性基中的一些数异或得到

  • 线性基没有异或和为 0 的子集

  • 线性基是保证前两个性质的基础上数的个数最少的一个

其实就是在数域 F2 下用位运算维护 F2n 的子空间的基。一个等价于原序列的极大无关组。

维护一个线性基,一般对于每一个二进制位 k 来维护一个序列中的数或能通过序列中的数异或出的数。这个数的最高位必须是就是 k

线性基支持的操作:(前4个 O(logn), 后两个 O(log2n)

  1. 加一个元素 x

    对与 x 的每一位,去看这个位置是不是已经放了数了,如果有数,把 x 异或上这个位置的数,这样可以保证 x 降低最高位的位置,并且等效替代了 x 。如果没有数,那么把 x 放到这个位置上去,并且结束循环。

    void add(ll x) {
    	for(int i = M; ~i; --i) if(x >> i & 1) {
    		if(c[i]) x ^= c[i];
    		else {c[i] = x; break;}
    	}
    }
    
  2. 询问最大值。

    从高位到低位贪心,如果当前数的第 i 位为 0,且极大无关组中有一个元素最 高位为 i,那么把当前数异或上这个元素即可。

    ll qry(ll ans = 0) {
    	for(int i = M; ~i; --i) if(c[i]) ans = max(ans, ans ^ c[i]);
    	return ans;
    }
    
  3. 询问是否能得到一个数 x

    就是要得到一个数与 x 异或是 0,就是要 x 在线性基中经过一通异或操作后的最小值是 0.

    bool chk(ll x) {
    	for(int i = M; ~i; --i) if(c[i]) x = min(x, x ^ c[i]);
    	return !x;
    }
    

    (代码未经验证,不保证正确性)

  4. 可离线删除元素

    对基中的每个元素维护其删除时间,由多个元素异或组合而成的元素的删除时间为 这些元素删除时间的最小值。

    插入时,贪心地,让基中的高位元素的删除时间尽量晚。还是从高位到低位枚举, 枚举到第 i 位时,如果当前插入元素的删除时间晚于基中第 i 位元素的删除时间, 那么二者交换。其余部分与普通线性基相同。

    查询时只考虑那些删除时间晚于当前时间的基元素即可。

    (还没写过代码)

  5. 在线删除元素

    如果被删除元素不是基中元素,直接删除即可,没有影响

    如果被删除元素是基中元素,那么需要消除它的影响 对每个基中元素 x 维护需要用 x 来表示的非基元素集合 Sx,用 Sx 中的任意一 个元素来代替 x 即可

    (还没写过代码)

  6. 求两个线性基的并

    把一个线性基的元素全部插入另一个即可

  7. 求两个线性基的交

    逐一判断一个线性基中的元素是否可以在另一个线性基中被表示即可

性质:可重性,可合并性。

Trie树一般用于维护一个数集S,可以支持询问x,找出S中一个数y,使得x异或y最大。

posted @   花子の水晶植轮daisuki  阅读(1)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
https://blog-static.cnblogs.com/files/zouwangblog/mouse-click.js
点击右上角即可分享
微信分享提示