思路来源
一些题目
2017 ACM-ICPC Asia Xi'an Problem A XOR(异或线性基 )
BZOJ2844
心得
本来是11月底学的这个东西,
这两天cf两场都出了异或线性基,
发现自己做题量还是不够,总结一下
cf1·11的G是个异或线性基的裸题
cf1·13的F是个异或线性基与线段树结合的题
在这里线段树的合并操作,就可以理解成两个异或线性基的并操作,
即将一个线性基加入到另一个线性基的过程
一些技巧
①求异或最大和
构造异或线性基,从高位到低位枚举,优先取高位
②求第k大值(不重复)
考虑有i个独立的基底,从小到大依次为b[i],共r个,由n个数构造
则类似二进制枚举,r个共可构造出(1<<r)个数,
先判0能不能取,若秩r<n则可取,否则不可取(线代基础解系与线性相关证明)
数不重复即每个只能出现一次,则第k大值,
若0可取,k--
然后压出k的二进制,在r个数里类似快速幂一样去取,
if(k&(1<<i))ans^=b[i]即可
题目(2022.12.31补充)
求线性基上第[l,r]大,依次输出,r-l<=2e5
将n个数插入线性基内,求得秩tot,
然后将矩阵化为上三角矩阵,使得对角线上的元素互不影响
假设对角线上有cnt个元素非0,则线性基可以异或出个数,
对于[l,r],依次求第k大即可,
因为本题题意约束,0一定可以由空集合取到,所以,无需判断秩tot<n
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10,M=61;
int n,tot;
ll l,r,a[N],k[M],cnt;
void insert(ll x){
for(int i=60;i>=0;i--){
if(x&(1ll<<i)){
if(k[i])x=x^k[i];
else{
tot++;
k[i]=x;
return;
}
}
}
}
ll ask(ll x){
if(x==1)return 0;
x--;
if(x>=(1ll<<cnt))return -1;
ll ans=0;
for(int i=0;i<=60;i++){
if(k[i]){
if(x%2)ans^=k[i];
x/=2;
}
}
return ans;
}
int main(){
scanf("%d%lld%lld",&n,&l,&r);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
insert(a[i]);
}
for(int i=0;i<=60;i++){
for(int j=1;j<=i;j++){
if(k[i]&(1ll<<(j-1)))k[i]^=k[j-1];
}
if(k[i])cnt++;
}
for(ll i=l;i<=r;++i){
printf("%lld%c",ask(i)," \n"[i==r]);
}
return 0;
}
③求Q的排名(允许重复)
考虑有i个独立的基底,从小到大依次为b[i],共r个,由n个数构造
注意到每个数出现的次数均为(1<<(n-r))
因为没被选入基底的数有n-r个,其能用基底唯一表示,再把基底对应选中一异或就变成0向量
故有n-r个零向量,其子集均为0向量,则任意一个可由基底构造出来的数res,
均可附加上这些零向量的子集,使之仍为res,
故每个可构造出来的数均出现每个数出现的次数均为(1<<(n-r))次
如何算Q对应的rank的最小值
设Q是由右起第a0,…,ai,…,am个向量异或而来,没有参与的向量置0
则考虑am…a1a0的二进制表示,显然比它小的数有amam-1…a1a0个,包括0
此处二进制是考虑右起出现的第i个线性基,故连续,不是线性基代表的b[i]的i
(1)如果0可取,
比它小的值的次数=每个数出现个数*比它小的值的个数
即(1<<(n-r))*am…a1a0的二进制表示
本身rank最小值=上述值+1
(2)如果0不可取,显然无零向量,即n=r,(1<<(n-r))=1
比他小的值的次数=比它小的值的个数=(am…a1a0的二进制表示)-1
本身rank最小值=((am…a1a0的二进制表示)-1)+1=am…a1a0的二进制表示
④求概率相等时异或和的期望(算每一位的贡献)
即BZOJ3811 k=1的情形
当ai这一位可以取1的时候,选上这个基与不选这个基各对应1/2的概率
而别的基ai这一位没有1,不管;
非线性基可以化成0向量,不管;
其实考虑非线性基不化成0向量的情形,也是若其ai这一位有1,选上1/2,不选1/2
且与ai那一位的基线性叠加,奇数个ai为1时有贡献,偶数个ai为1时没贡献,
这样同时选和同时不选是1/2,选1个是1/2
以上为2个的情形,合并考虑,数学归纳可证m个ai这一位有1的情形
故每一位出现的概率均为1/2,
这个和的期望,等于单独考虑可能出现的每一位的期望的线性和,
而每一位出现的概率均为1/2,
故答案为,线性基取或的最大值(不如说是n个数取或的最大值,即令每一个可能出现的位都出现)的1/2
⑤暴力枚举子集算和的期望的技巧
即BZOJ3811 k>=3的情形
设有x个可能出现的数,即线性基秩为r时,x==(1<<r)
此题答案不超过(1<<63),但中间计算sigma(x个可能出现的数),再除以x时,sigma可能爆LL
故开一个高位,开一个低位,
高位ans保存>x的位,低位res保存<x的位
即ans=sigma/x,res=simga%x
由于x是2的倍数,即ans+=(res>>x),res&=(x-1)即可
当x是2的倍数时,res&=(x-1)与res%=x等价,都是去掉高于x-1那一位的1嘛
⑥异或环和
即BZOJ2115
无向图,
1->n的任一路径异或和,等于1->n的某一路径异或和,和某一环的异或和
画个图就能证明,把环的一部分异或掉,异或上另一部分
和那个做功与路径无关的无旋场上的环很像,但这里正是通过环来改变权值
假设有一个a->c->b->d->a的环,原来是一条包含a->c->b的路径,异或上这个环,就变成了a->d->b的路径
待填坑
CF0113 F题 线段树+线性基
2017 ACM-ICPC Asia Xi'an Problem A XOR(异或线性基 )
BZOJ3811 求期望的k=2的情形,分1/2,1/4,0三种情况讨论
回头整理一个linear_base的板子吧