码迷,mamicode.com
首页 > 其他好文 > 详细

线性基

时间:2019-11-02 18:12:22      阅读:59      评论:0      收藏:0      [点我收藏+]

标签:scan   log   can   开关   个数   long   pre   它的   htm   

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);
}

  

 

线性基

标签:scan   log   can   开关   个数   long   pre   它的   htm   

原文地址:https://www.cnblogs.com/hgangang/p/11783101.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!