• 线性基求交


    学弟 linshey 在怒刷候选队互测 uoj#698 时提出了一个著名的问题:给定两组线性基 \(A=\{u_1,u_2,\cdots,u_a\},B=\{v_1,v_2,\cdots,v_b\}\),它们形成的线性空间的交怎么用一组线性基 \(C\) 表示呢?

    仔细想想这个问题并不简单,因为如果简单地用 \(A\) 中所有能被 \(B\) 表示的基向量组出 \(C\) 的话是不对的,完全可能基向量不在 \(B\) 中但它们的线性组合在 \(B\) 中,如 \(A=\{5,3\},B=\{6\}\)

    那么可能可以考虑重构一下 \(A\),尽量用在交空间中的向量来表示 \(A\)

    如何找出一个非平凡的向量 \(w\) 使其在 \(A\cap B\) 中呢?我们不妨钦定 \(u_1\) 必选以避免 \(0\),那么尝试用剩余的所有向量即 \((A\setminus u_1)\cap B\) 来表示 \(u_1\)。如果表出来了令 \(w\) 为在 \(B\) 中的向量的异或和以代替 \(u_1\) 即可,否则包含 \(u_1\) 的向量都不在 \(B\) 中,删去 \(u_1\) 即可。

    可以发现这样处理之后交空间不变且问题得到了简化,那么继续对 \(u_2,u_3,\cdots,u_a\) 进行这样的处理,剩下的向量组 \(A'=\{w_1,w_2,\cdots,w_{a'}\}\) 满足每个基向量都在 \(B\) 中,于是 \(A\cap B=A'\cap B=A'\),构建 \(A'\) 的线性基即为答案。

    整个流程的复杂度瓶颈在于表示每个 \(u_i\) 时构建当前 \((A\setminus u_i)\cap B\) 的线性基。可以发现构建时 \(u_i\) 以前的向量都在 \(B\) 中从而不会产生贡献,我们只需构建 \(A_{i+1},\cdots,A_a\)\(B\) 的并的线性基,而这可以通过后缀和处理。

    那么整个算法过程就是:

    构建辅助线性基 \(D=B\)
    按顺序考虑 \(i=a,a-1,\cdots,1\)

    1. 尝试用 \(D\) 表出 \(u_i\),若成功则取出 \(w=\) 所有在 \(B\) 中的向量的异或和 以更新 \(C\)
    2. \(u_i\) 更新 \(D\)(更新时保持原有基向量不变就可避免属于 \(B\) 的部分被修改)。

    如果认为异或运算 \(O(1)\) 那么算法复杂度为 \(O(\log^2 A)\),其中 \(A\) 是值域,应该是比较优秀的。

  • 相关阅读:
    浅谈CSS3 Filter的10种特效
    简评Photoshop CC新增的复制CSS功能
    首页背景图自适应
    CSS常用浮出层的写法
    隐藏"站长统计"图标
    响应式网站代码收集整理
    【leetcode❤python】 58. Length of Last Word
    【leetcode❤python】 88. Merge Sorted Array
    【leetcode❤python】 234. Palindrome Linked List
    【leetcode❤python】 20. Valid Parentheses
  • 原文地址:https://www.cnblogs.com/LinZhengyu/p/16381207.html
Copyright © 2020-2023  润新知