线性基求交

Posted mollnn

tags:

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

设有两个线性基 (alpha,eta),如果 (eta_i) 能被 ( heta igcup phi, heta subseteq alpha,phi subseteq {eta_0,eta_1,...,eta_{i-1}}) 表示,则把 ( heta) 加入答案线性基即可

#include <bits/stdc++.h>
using namespace std;

#define int long long

struct linearbase
{
    int a[64];
    linearbase()
    {
        memset(a,0,sizeof a);
    }
    void insert(int k)
    {
        for(int j=60; j>=0; --j)
            if((k>>j)&1ll)
                if(a[j]==0)
                {
                    a[j]=k;
                    break;
                }
                else k^=a[j];
    }
    int& operator [] (int i)
    {
        if(i<64) return a[i];
    }
    bool check(int x)
    {
        for(int i=60; i>=0; --i)
        {
            if((a[i]^x)<x) x^=a[i];
        }
        return x==0;
    }
    void print()
    {
        cout<<"Linear Base Output"<<endl;
        for(int i=60;i>=0;--i) if(a[i]) cout<<i<<": "<<a[i]<<endl;
        cout<<"-----"<<endl;
    }
    friend linearbase operator *(linearbase a,linearbase b)
    {
        linearbase all,c,d;
        for(int i=60;i>=0;--i)
        {
            all[i]=a[i];
            d[i]=1ll<<i;
        }
        for(int i=60;i>=0;--i)
        {
            if(b[i])
            {
                int v=b[i],k=0,fg=1;
                for(int j=60;j>=0&&fg;j--)
                {
                    if(v>>j&1)
                    {
                        if(all[j]) v^=all[j],k^=d[j];
                        else all[j]=v,d[j]=k,fg=0;
                    }
                }
                if(fg)
                {
                    int v=0;
                    for(int j=60;j>=0;j--)
                    {
                        if(k>>j&1) v^=a[j];
                    }
                    c.insert(v);
                }
            }
        }
        return c;
    }
    int solve() {
        int ans = 0;
        for(int i=60; i>=0; --i)
            if((ans^a[i]) > ans) ans^=a[i];
        return ans;
    }
};

signed main()
{
    linearbase a,b;
    a.insert(1);
    a.insert(2);
    b.insert(3);
    linearbase c=a*b;
    a.print();
    b.print();
    c.print();
}

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

线性基求交板子

[hdu3949]XOR(线性基求xor第k小)

面向对象 (11)求交并集 判断字符形式

LibreOJ #2013. 「SCOI2016」幸运数字

线性基bzoj2844: albus就是要第一个出场

[bzoj4184]shallot