模板:线性代数

线性基

异或线性基

若要查询第k小子集异或和,则把k写成二进制,对于是1的第i位,把从低位到高位第i个不为0的数异或进答案。若要判断是否有非空子集的异或和为0,如果不存在自由基,那么说明只有空集的异或值为0,需要高斯消元来判断。

struct BaseXOR
{
    vector<ll> a;
    BaseXOR():a(64,0) {}
    ll ask()//查询最大子集异或和
    {
        ll t=0;
        for(int i=a.size()-1; ~i; --i)
            t=max(t,t^a[i]);
        return t;
    }
    bool add(ll x)
    {
        for(int i=a.size()-1; ~i; --i)
            if(x>>i&1)
            {
                if(a[i])x^=a[i];
                else return a[i]=x,1;
            }
        return 0;
    }
    bool check(ll x)//判断一个数是否能够被异或出,0根据需要特判
    {
        for(int i=a.size()-1; ~i; --i)
            if(x>>i&1)
                if(x^=a[i],!x)
                    return 1;
        return 0;
    }
};

向量线性基

add返回要插入的向量z是否与已插入的线性无关。

struct Base
{
    vector<vector<double> > v;
    Base(int N):v(N,vector<double>(N,0)) {}//R^N的子空间
    bool add(vector<double> x)
    {
        for(int i=0; i<x.size(); ++i)
            if(fabs(x[i])>EPS)
            {
                if(fabs(v[i][i])<EPS)return v[i]=x,1;
                double t=x[i]/v[i][i];
                for(int j=0; j<x.size(); ++j)
                    x[j]-=t*v[i][j];
            }
        return 0;
    }
};

矩阵

struct Matrix
{
    static int n;
    ll a[N][N];
    Matrix(ll k=0)
    {
        memset(a,0,sizeof(a));
        for(int i=0; i<n; ++i)a[i][i]=k;
    }
};
Matrix operator*(const Matrix &A,const Matrix &B)
{
    Matrix R(0);
    for(int i=0; i<R.n; ++i)
        for(int j=0; j<R.n; ++j)
            for(int k=0; k<R.n; ++k)
                R.a[i][j]=(R.a[i][j]+A.a[i][k]*B.a[k][j])%INF;
    return R;
}
Matrix pow(Matrix a,int b)
{
    Matrix r(1);
    for(; b; b>>=1,a=a*a)
        if(b&1)r=r*a;
    return r;
}
ll det(Matrix a)//矩阵a的n阶行列式
{
    ll ans=1;
    for(int i=0; i<a.n; ++i)
    {
        for(int j=i+1; j<a.n; ++j)
            while(fabs(a[j][i])>EPS)
            {
                ll t=a[i][i]/a[j][i];
                for(int k=i; k<n; ++k)
                    a[i][k]-=t*a[j][k],swap(a[i][k],a[j][k]);
            }
        if(fabs(ans*=a[i][i])<EPS)return 0;
    }
    return ans;
}
void gauss_elimination(Matrix &A)
{
    int n=a.n/*-1*/;//A为增广矩阵,要求n*n的系数矩阵可逆,运行结束后A[i][n]为第i个未知数的值,这个-1看情况去掉注释
    for(int i=0; i<n; ++i)//消元
    {
        int r=i;//选一行r和第i行交换
        for(int j=i+1; j<n; ++j)
            if(fabs(A[r][i])<fabs(A[j][i]))
                r=j;
        if(r!=i)swap(A[i],A[r]);
        for(int j=n; j>=i; --j)//与i+1~n行进行消元,必须倒序循环
            for(int k=i+1; k<n; ++k)
                A[k][j]-=A[k][i]*A[i][j]/A[i][i];
    }
    for(int i=n-1; ~i; --i)//回代
    {
        for(int j=i+1; j<n; ++j)
            A[i][n]-=A[j][n]*A[i][j];
        A[i][n]/=A[i][i];
    }
}
阅读更多
版权声明:本文为博主原创文章,欢迎转载并注明来源。 https://blog.csdn.net/w_weilan/article/details/79975433
个人分类: acm 模板
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭