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

线性基求交

时间:2020-07-06 10:50:13      阅读:53      评论:0      收藏:0      [点我收藏+]

标签:struct   size   void   end   out   friend   code   ems   str   

设有两个线性基 \(\alpha,\beta\),如果 \(\beta_i\) 能被 \(\theta \bigcup \phi, \theta \subseteq \alpha,\phi \subseteq \{\beta_0,\beta_1,...,\beta_{i-1}\}\) 表示,则把 \(\theta\) 加入答案线性基即可

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

线性基求交

标签:struct   size   void   end   out   friend   code   ems   str   

原文地址:https://www.cnblogs.com/mollnn/p/13253408.html

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