线性积 、基环树、卡特兰树
来自学姐的课件
线性基
首先清楚一些定义,线性基是对于一个序列来说
每个序列都至少有一个线性基,满足以下性质:
-
原序列中的每个数都可以由线性基当中的若干个数异或得到,但不限于这些数
-
线性基中的任意个数异或起来都不能为零
-
线性基中存在的数最少
再来解释一下为什么至少有一个线性基,在满足以上性质的条件下,也可以有多个不同形态的线性基存在的数目都是最少的
也就是线性基其实并不唯一
线性基的构造
既然是异或,就要将数进行二进制拆分
对于每个数在线性基中的插入,从最高位向低位扫一遍,如果当前位存在,进行插入
- 第位线性基为零可直接进行插入
- 如果存在已经插入过的数,那么将要插入的与这一位的线性基进行异或
解释一下为什么要进行异或,任何一个不为零的数最高位都是,当前线性基中存在数说明两个数的最高位相同,异或一下得到一个新的数,再看接下来新的最高位如何插入。
void Ins(ll x) { for(int i=50;i>=0;--i) { if(!(x&(1LL<<i))) continue; if(p[i]) x^=p[i]; else { p[i]=x; break; } } }
理解了构建的插入操作,那么接下来就比较简单了
最大异或和
利用刚刚学到的性质,构造出来的线性基可以异或得到原序列当中或原序列中异或起来得到的任意数
同样从高往低扫,如果这一位异或使答案更大就异或上这一位
ll getmax() { ll res=0; for(int i=50;i>=0;--i) { if((res^p[i])>res) res^=p[i]; } return res; }
最小异或和
自然就是反过来的思路,从低往高扫
唯一不同的一点就是,如果构造时有的数无法插入,那么代表原序列存在异或和为零的子集,此时最小值直接返回零即可。
last
最后有几点提醒:
- 因为存在线性基中异或值不能为零的性质,所以会存在有的数最终无法插入的情况
- 构造线性基时注意位数,必要的时候开
然后就是一些习题,大家课下可以做一做
基环树
个节点条边,在树的基础上多了一条边构成了一个环
- 无向树,边为无向边
图为有向边构成 - 内向树,每个点出度为一
- 外向树,每个点入度为一
一般可以将环缩为一个点后以其为根进行树上操作,找出来的环再进行单独处理
找环
- 无向树
拓扑排序/都可以,直接找环 - 内向树
存在一个性质,每个点出度唯一,意味着从任意点开始走都可以到达“环” - 外向树
边的方向恰好与内向树相反,建边的时候可以直接反向改造为内向树找环
基环树
题意就是求树的带权最大独立集
需要断掉其中的一条边将基环树转化成一棵树 处理环就是枚举每个元素选不选
由于切掉边的两端是不能同时选的,所以每次断边时需要计算两次,取最大值
转化成树形以后就是上司的舞会的转移模型了
几道练习
卡特兰数
是数学里面比较有用的东西 高考课有时会用到:
01序列等同于合法括号匹配
大概用途
- 一个点到另一个点不触碰/越过某条斜线的方案数
- 合法括号匹配,即每个前缀当中左括号数目始终大于等于右括号的数目
- 二叉树有多少种不同的建立形态
- 圆内弦,圆上个点,两两配对后弦互不相交的方案数
数列
- 1,1,2,5,14,42,132,429,1430,4862,16796,58786,208012...
- 转化为坐标系上面从到,每次只能向右或者向上走一步
即左括号/数字0看作向右走一步,右括号/数字1看作想上走一步->不越过这条斜线的方案数
递推
- 正常从到的方案数为,不越过直线转化为不触碰直线记录不合法的方案数
组合数整理一下得到另一种形式
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】