• 线性基复习


    以前线性基学了三天 写了一些题目。

    到现在 线性基? 线性基是啥??线性基有啥用啊???

    果然 人类最大的敌人 是遗忘 忘了 就什么也没有了。

    但有些事情是不能忘记的 曾经的创伤 依然在深夜 隐隐作痛。知识也是如此 我们要一直铭记。

    以前写的线性基总结:LINK:Idearlist

    这个上面写了关于我自己想的好多的证明 和一些题目的讲解。

    这里我列举一些线性基的有关知识。

    定义

    线性基 也叫作 异或空间的一组基底,异或空间是对异或运算的封闭空间。

    一组向量 其异或空间的基底大小固定。基底可以异或出所有向量 基底是最大的异或无关子集。

    构造

    考虑如何构建 一个序列的线性基。选出任意一些数字使得 这些数字异或出来可以 张成整个异或空间。

    线性基存在替换关系 但构造和替换无关 将一个元素加入到线性基中看线性基是否可以组成当前数字如果可以 那么显然这个数字没有用。

    所以我们不断加入即可。判断时 显然从高位开始异或。

    const int MAXN=100010;
    int a[MAXN];
    int f[60],cnt;
    inline void structure(int x)
    {
        for(int i=60;i>=0;--i)
            if(x&(1<<i))
            {
                if(!f[i]){++cnt;f[i]=x;break;}
                else x^=f[i];
            }
    }
    

    可以看出这其实是在解异或方程组。
    什么?你说你看不出来?原因是这样的 这个线性基中存的并非是我们原来的数字 而是和其他数字异或之后的结果 拿这种结果使用 由于异或的自反性所以是正确的。

    对于我们当前的线性基 我们解异或方程 这样解也是极为快速 方便的。

    引理:一个线性基中的元素个数不可能大于这个线性基的最大维度。

    考虑 求出一个序列任意个数字 使其异或最大。

    先求出这个序列的线性基 那么这个线性基 可以代表整个序列了。

    考虑求最大值 从高位到低位贪心 可以发现这样显然是正确的。

    考虑最小值。可以证明最小值即为我们线性基中的最小值。

    修改

    没啥好说的 谁都会暴力重构。。。

    合并

    没啥好说的 谁都会暴力重构。。

    删除

    没啥好说的 谁都会暴力重构。

    上一道小例题 LINK:bzoj 2115 Wc2011 Xor

    给出一张有向有向无环图 求图中一条1~n的路径 使其异或和最大。

    显然 这条路径不一定是简单路径。考虑图是一颗树的话 路径唯一。

    有环会怎么样 这说明我们可以先跑到环上去再跑回来 且 环的异或值会被我们得到。

    我们发现图中的任意一个环我们都是可以得到的。我们考虑将环的权值加到线性基中。

    考虑 一条从1到n的路径 如果有多条我们显然可以随便取一条因为这一条如果不是最优解可以异或一下环来得到最优。

    可以发现我们无法把图中所有环放到线性基中 但是可以发现环和环的异或可以得到其他环。

    这启示我们 只需要放入一些环即可。显然我们构造出dfs树 将其出现的环加入到线性基中即可。

    最后利用dis 和线性基 来取异或最大值即可。

    const int MAXN=100010;
    int n,m,len;
    int vis[MAXN];ll f[70],d[MAXN];
    int lin[MAXN],ver[MAXN<<1],nex[MAXN<<1];ll e[MAXN<<1];
    inline void add(int x,int y,ll z)
    {
    	ver[++len]=y;
    	nex[len]=lin[x];
    	lin[x]=len;
    	e[len]=z;
    }
    inline void insert(ll x)
    {
    	//cout<<x<<endl;
    	for(int i=60;i>=0;--i)
    		if(x&(1ll<<i))
    		{
    			if(!f[i]){f[i]=x;break;}
    			else x=x^f[i];
    		}
    }
    inline void dfs(int x)
    {
    	vis[x]=1;
    	go(x)
    	{
    		if(vis[tn])insert(d[x]^d[tn]^e[i]);
    		else d[tn]=d[x]^e[i],dfs(tn);
    	}
    }
    inline ll ask(ll x)
    {
    	for(int i=60;i>=0;--i)
    		if((x^f[i])>x)
    			x=x^f[i];
    	return x;
    }
    int main()
    {
    	freopen("1.in","r",stdin);
    	get(n);get(m);
    	rep(1,m,i)
    	{
    		int x,y;ll z;
    		get(x);get(y);get(z);
    		add(x,y,z);add(y,x,z);
    	}
    	dfs(1);
    	printf("%lld
    ",ask(d[n]));
    	return 0;
    }
    
  • 相关阅读:
    Document
    Document
    Document
    Document
    Document
    Document
    8. vue 的生命周期
    7. vue-cli 安装和使用脚手架
    5.组件(2) 之 父级传子级
    6.组件(3) 之 子级传父级
  • 原文地址:https://www.cnblogs.com/chdy/p/12521249.html
Copyright © 2020-2023  润新知