线性基

Posted hgangang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性基相关的知识,希望对你有一定的参考价值。

https://www.cnblogs.com/downrainsun/p/11228690.html

完成套路:往自己这里搬。

性质:

设数集T的值域范围为[1,2^n−1]。 
T的线性基是T的一个子集A={a1,a2,a3,...,an}。 
A中元素互相xor所形成的异或集合,等价于原数集T的元素互相xor形成的异或集合。 
可以理解为将原数集进行了压缩。

性质
1.设线性基的异或集合中不存在0。 
2.线性基的异或集合中每个元素的异或方案唯一,其实这个跟性质1是等价的。 
3.线性基二进制最高位互不相同。 
4.如果线性基是满的,它的异或集合为[1,2^n−1]。 
5.线性基中元素互相异或,异或集合不变。

接下来是题目:

一,洛谷彩灯

给你m个开关,每个开关表示可以控制哪些灯的状态,且状态取反,亮则暗,暗则亮,求多少种不重复的灯亮状态

题解:首先可以知道的是那些开关实际上就是异或操作,那么考虑到不重复,那就想到线性基

线性基性质A中元素互相xor所形成的异或集合,等价于原数集T的元素互相xor形成的异或集合。,同时不出现重复,那接下来就好办了,成功解决不重复问题,就算线性基有多少个数存在,然后2的个数次方就完事

#include <cstdio>
#include <cstring>
#define ll long long

int n,m;
ll d[60];
char s[60];
void add(ll x)
{
    for(int i=50;i>=0;i--)
    {
        if(x&(1ll<<i))
        {
            if(d[i]==0)
            {
                d[i]=x;
                return;
            }
            else x^=d[i];
        }
    }
}

int main()
{
    scanf("%d %d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%s",s+1);
        ll x=0;
        for(int j=1;j<=n;j++)
        if(s[n-j+1]==‘O‘)x^=(1ll<<(j-1));
        add(x);
    }
    int ans=0;
    for(int i=0;i<=50;i++)
    if(d[i]!=0)ans++;
    printf("%lld",(1ll<<ans)%2008);
}

  

 

以上是关于线性基的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 4269 再见Xor 线性基

Codeforces 1100F(线性基+贪心)

线性基 刷题记录

P3857 [TJOI2008]彩灯(线性基)

线性基讲解

线性基入门