『2019Summer Algorithms』
一个暑假两次集训,感觉学了好多好多的东西,也挖了好多好多的坑,于是就决定写一篇关于算法的总结,用于熟悉新算法,也留下一点对新算法的理解。
AC自动机
简单的说就是在\(trie\)树上实现\(KMP\),用于多模式串的匹配。
而\(AC\)自动机的理解就在于\(fail\)指针,\(fail\)指针是实现多模式串匹配的关键。每次匹配失败后,\(fail\)指针会指向一个当前匹配串的最长真后缀,数次跳跃后,就能实现对文本串的一段在\(trie\)树进行所有可能的匹配。
而对于\(fail\)指针的求解,用\(bfs\)实现。\(AC\)自动机的时间复杂度是线性的(一般情况下)。
好像\(AC\)自动机还有一个拓扑建图优化,还没有学。
manacher算法
\(manacher\)算法用于求解一个字符串每一个位置的最长回文字串。
这个算法其实和\(KMP\)的思想差不多,只要用已知信息去推后面的信息就可以了。具体地,可以记录当前最大的回文右端点,然后画一下对称图,就可以推了,不是很难。
博客这篇,模板题这里,可以看\(HL\ Day4\)的课件。
ExKMP算法
\(KMP\)算法的拓展,又称\(z-algorithm\),用于求解以下问题:
给你两个字符串\(s,t\),长度分别为\(n,m\),请输出\(s\)的每一个后缀与t的最长公共前缀。
思想和\(KMP\),\(manacher\)都是一样的,就是从前往后推。由于相邻两个位置的答案有很大一部分是重复匹配的,所以可以根据上一次的答案考虑,需要分两种情况讨论。
不是很好写,好像下标还只能从\(0\)开始,从\(1\)开始会非常别扭。
块状树
把分块思想放在树上,就是树分块。
用\(dfs\)遍历树,把连续遍历到的一段节点加在一个块里。然后就可以对树子树信息进行维护了。
还是和分块一样,块内设法直接维护,边角暴力。这样进行分块是可以支持修改和动态加点的,但是不是稳定算法,会被菊花图卡掉。
模板题这里。
树同构
也可以说是树哈希算法,主要用于判定树的形态。
一般来说用的是最小表示法,像树形\(dp\)一样,先获取每个子树的\(hash\)值,然后组合成一个新的序列,再\(hash\)一个值返回即可。
当树是无根树的时候,还要先找以下重心作为根,当然也要考虑双重心的情况。
模板题这里。
类欧几里得算法
好像和欧几里得算法没什么关系,是用来计算整除求和式的。
主要思想就是分类,然后分治,比欧几里得算法稍微复杂一点,就是推公式吧,套路还是拆一下求和式,下取整。
模板题这里。
整体分治
简单的说就是对于多个询问同时进行二分答案,像二分答案一样判定询问的真实答案位于哪一侧,然后对询问进行分类,就变成一个分治算法了。
真正理解点在于询问分类,这是分治算法的核心,得到的子问题是独立的。这样就可以理解为什么修改操作也能参与分类了。
代码上就是要想好用什么数据结构来维护贡献,然后注意操作的时间顺序就可以了。
模板题:K大数查询,Dynamic Rankings,可以看蓝书。
线段树分治
和\(cdq\)分治一样,是时间分治的一种。
就是对时间建线段树,然后把一个时间段内存在的操作打在线段树的\(log\)个区间节点上。而对于一个时间点的询问,就对应了线段树的一个叶节点,所以只需将询问挂在叶节点上即可。
在线段树上处理完所有操作和询问后,对整棵线段树\(dfs\)一次,向下访问时依次处理掉节点上的操作,到达叶节点就回答掉询问,向上回溯时就撤销掉操作。
别的都很简单啊,想好用什么数据结构维护操作(要支持撤销)即可。
后缀数组
实际上是后缀排序,只学了\(O(nlog_2n)\)倍增法。
其实倍增就体现在排序的长度上,每一次排序只根据每个后缀的前二的幂次为来排一个相对位置,在\(O(log_2n)\)次排序后就能得到最后的排名。
每一次当中如何排序呢?用双关键字的基数排序,时间复杂度的\(O(n)\)的。我们取\((rank1_i,rank2_i)\)作为排序的双关键字,\(rank1_i\)指的是后缀\(i\)上一次排序后的排名,而\(rank2_i\)指的是后半部分后缀上一次排序后的排名,相当于倍增\(2^k\)过程中一个管辖前\(2^{k-1}\)个字符,一个管辖后\(2^{k-1}\)个字符。
如果是\(sort\)的话,这样就已经可以了,但是时间复杂度是\(O(nlog^2n)\)。
基数排序如何实现?我们还得记一下\(pos_i\):第二关键字排名为\(i\)的后缀位置。这样就可以在基数排序的时候定位第二关键字了。
\(height\)数组怎么求,最重要的性质就是\(height[rank[i]]\geq height[rank[i-1]]-1\),然后就可以利用单调性求了。
后缀数组好像有很多经典的运用,还没有学完。
快速傅里叶变换
最直接的运用就是计算多项式乘法。
很简单的思路,系数表达法做乘法太慢,就用点值表达法做乘法。于是想办法搞一个算法可以在\(O(nlog_2n)\)的时间内在系数和点值之间做转换,就是\(FFT\)在做的事情。
思路是分治,\(n\)个点我们带入\(n\)个不同的单位根,我们发现当对多项式根据次数奇偶性分类后,可以计算一半得到另一半的值,于是就能递归下去了。
最后的优化就是把递归省了,发现可以用二进制的\(bit-reverse\)来搞。
快速数论变换
发现把\(FFT\)的单位根换成原根,折半引理和消去引理照样成立,于是就有了模意义下的\(FFT\)。
分治FFT
要算一个卷积,但是发现卷积计算式中有一项和我们未计算的值有关。
于是可以想到\(cdq\)分治,每一次尝试计算左边对右边的贡献即可。计算贡献时,发现还是一个卷积,\(NTT/FFT\)即可。
Edmonds-Karp增广路
求网络最大流。
先是\(FF\)算法的思想,找到一条增广路就增广。但是这样时间复杂度是不对的,上限可达\(O(m|f_{max}|)\)。
可以证明,每次找最短路径增广路,增广次数不会超过\(O(nm)\)次,然后\(EK\)增广路就诞生了。
模板题这里,博客已经写了。
dinic算法
\(EK\)增广路的优化。
多数时候最短路径增广路不止一条,于是就能想到多路同时增广。实现的时候还要加上若干剪枝,就可以证明时间复杂度是\(O(n^2m)\)的\(dinic\)算法了。
模板题这里,博客已经写了。
费用流
没什么意思,把最大流的最短路径增广路用用最短路算法跑一下就可以了。
一般来说直接\(SPFA\)即可,加个\(johnson\)算法的势函数优化也可以用\(dijkstra\)。
还有一种思路就是学\(KM\)算法的改顶标,只需满足三角形不等式即可。这样的\(zkw\)费用流在稠密图上效率比较高,就是不能跑负权图(最大费用最大流)。
2-sat模型
就是考虑命题之间的推导关系,在图上连的是有向边,当然逆否命题之间也要连边。
然后考虑矛盾性,只要用\(tarjan\) \(SCC\)缩点即可。如果要输出一组可行解,只需自底向上执行拓扑排序即可。当然,利用\(tarjan\)的性质可以很方便的写出代码。
看蓝书吧。
二分图
先是二分图判定,可以用染色法,不断给相邻节点标不同的颜色,然后看一看哟没有冲突即可。
二分图匹配,可以直接跑最大流,或者用匈牙利算法。匈牙利算法的本质就是不断找增广路,找到了就对路径上的边取一下反,这样最大匹配的大小就会增加\(1\)。
二分图带权匹配,可以直接跑费用流,也可以用\(KM\)算法。\(KM\)算法的思路就是通过合法修改顶标的手段不断扩大相等子图。不过,\(KM\)算法只有在带权最大匹配是完备匹配时才能用。
Link-Cut-Tree
要维护一棵树的链信息,需要支持动态加边,删边。
方法是链剖,不过是实链剖分,要用一堆\(splay\)来维护。核心操作是\(access\),如何理解?虚实链其实是自己定义的,我们只要维护好打通一条实链的正确\(splay\)森林即可,这样链信息就是可以正确维护的,并且时间复杂度是\(O(log_2n)\)。
操作有点多,但是码量不大,需要注意一些细节,在完成代价为树高的操作时别忘了\(splay\)一下保证时间复杂度。
后缀自动机
一个很鬼畜的自动机,\(endpos\)等价类维护成一个状态,字符维护成转移,再加一些后缀链接就以高度压缩的形式维护了一个字符串的所有子串信息。
难点在于构建,其实核心就是那三种情况的分类讨论。而最难理解的就是第三种情况,其实\(clone\)一个点的本质就是一个\(endpos\)等价类的两个子串一个不属于同一个\(endpos\)等价类了,必须分裂一个状态才能正确地维护后缀链接。
用法好像有很多,还是很会,但是代码挺短的。
杜教筛
求积性函数的前缀和。
没啥神奇的,就是对一个函数做一下狄利克雷卷积,发现推出了一个子问题,还可以用整除分块来做,于是就变成了记忆化搜索。
可以用线性筛先预处理一些值,然后再记忆化搜索时间复杂度就是\(O(n^{\frac{2}{3}})\)的。
杜教筛的时间复杂度瓶颈是整除分块,所以求狄利克雷卷积的另外两个数论函数的时间复杂度要求是根号的,不一定要\(O(1)\),甚至还可以套杜教筛。
模板题这里,可以看\(R\)爷课件。
Miller-Rabin 算法
素性判定的\(RP\)算法,时间复杂度\(O(log_2n)\)。
两个步骤,费马小定理和二次探测定理,没什么好说的,当取\(10\)个质数的时候出错率几乎为\(0\)。
Pollards'Rho 算法
基于\(Miller-Rabin\)的质因子分解算法,期望复杂度\(O(\sqrt[4]{n}log_2n)\)。
原理其实是基于生日悖论,每次用两个随机数的差尝试分解成功概率更大。而随机数的生产就是用\(x_i=x_{i-1}^2+c\)的形式,保证分布均匀。
随机数可能尝试模意义下的环,就用倍增标记的方法判就可以了。
模板题这里。
『2019Summer Algorithms』的更多相关文章
- 似魔鬼的 『 document.write 』
在平时的工作中,楼主很少用 document.write 方法,一直觉得 document.write 是个危险的方法.楼主不用,并不代表别人不用,最近给维护的项目添了一点代码,更加深了我对 &quo ...
- 拾遗:『Linux Capability』
『Linux Capability』 For the purpose of performing permission checks, traditional UNIX implementations ...
- 『创意欣赏』20款精致的 iOS7 APP 图标设计
这篇文章给大家分享20款精致的 iOS7 移动应用程序图标,遵循图形设计的现代潮流,所有图标都非常了不起,给人惊喜.通过学习这些移动应用程序图标,设计人员可以提高他们的创作,使移动用户界面看起来更有趣 ...
- 『设计前沿』14款精致的国外 iOS7 图标设计示例
每天都有大量的应用程序发布到 iOS App Store 上,在数量巨大的应用中想要引起用户的主要,首要的就是独特的图标设计.这篇文章收集了14款精致的国外 iOS7 图标设计示例,希望能带给你设计灵 ...
- Github 恶搞教程(一起『玩坏』自己的 Github 吧)
最近在伯乐在线读到一篇趣文,<如何在 Github『正确』做贡献>,里面各种能人恶搞 Github 的『Public contributions』,下面截取几个小伙伴的战绩: 顺藤摸瓜,发 ...
- 『创意欣赏』30幅逼真的 3D 虚拟现实环境呈现
又到周末了,给大家分享30幅漂亮的 3D 虚拟现实环境呈现,放松一下.这些创造性的场景都是通过 3D 图形设计软件,结合三维现实环境渲染制作出来的.一起欣赏:) 您可能感兴趣的相关文章 20幅温馨浪漫 ...
- [TYVJ1827]『Citric II』一道防AK好题
时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 第二届『Citric杯』NOIP提高组模拟赛第一题 描述 Lemon认为在第一届『Citric』杯模拟赛中出的 ...
- 办理滑铁卢大学(本科)学历认证『微信171922772』UW学位证成绩单使馆认证University of Waterloo
办理滑铁卢大学(本科)学历认证『微信171922772』UW学位证成绩单使馆认证University of Waterloo QQ/微信171922772办理毕业证成绩单.真实使馆及教育部学历认证★诚 ...
- 办理渥太华大学(本科)学历认证『微信171922772』Ottawa U学位证成绩单使馆认证University of Ottawa
办理渥太华大学(本科)学历认证『微信171922772』Ottawa U学位证成绩单使馆认证University of Ottawa QQ/微信171922772办理毕业证成绩单.真实使馆及教育部学历 ...
随机推荐
- 面试官:讲讲redis的过期策略如何实现?
时隔多日,小菜鸡终于接到阿里的面试通知,屁颠屁颠的从上海赶到了杭州. 经过半个小时的厮杀: 自我介绍 hashMap和ConcurrentHashMap区别 jdk中锁的实现原理 volatile的使 ...
- day 67
目录 Vue框架 Vue的简介 Vue的使用 插值表达式 文本指令 事件指令 属性指令 Vue框架 Vue的简介 Vue是一套构建用户界面的框架,与Angular.React两个框架相比,Vue吸取了 ...
- django framework插件类视图分页
分页 继承APIView类的视图中添加分页 from rest_framework.pagination import PageNumberPagination class MyPageNumberP ...
- 【前端_React】Node.js和webpack的安装
第一步——安装Node.js 首先要安装Node.js,Node.js自带了软件包管理工具npm,可以使用npm安装各种插件.Node.js的下载地址 可以自定义安装到指定的路径下,待安装完成后命令行 ...
- Python--RE--?
?在re中默认匹配前一个字符0次或者1次 比如: aal? 默认匹配aal,或者aa 即整体匹配前一个字符串,但是可以舍弃最近的一个字符或者不舍弃 re模块 常用正则表达式符号 '.' 默认匹配 ...
- css 高度随宽度比例变化
[方案一:padding实现] 原理: 一个元素的 padding,如果值是一个百分比,那这个百分比是相对于其父元素的宽度而言的,padding-bottom 也是如此. 使用 padding-bot ...
- opencv2配置window
https://opencv.org/ opencv2 opencv3 opencv4 (现在到4版本) 二值化 图像拉伸 灰度 图像腐蚀 车牌识别 配置:https://blog.csdn.n ...
- react.js知识汇总
首先ract的基本结构 var Input = React.createClass({ getInitialState: function() { return {value: 'Hello!'}; ...
- windows下apache + mod_wsgi + python部署flask接口服务
windows下apache + mod_wsgi + python部署flask接口服务 用python3安装虚拟环境 为啥要装虚拟环境? 原因1:安装虚拟环境是为了使项目的环境和全局环境隔离开,在 ...
- 关于python切片操作笔记
一. Python可切片对象的索引方式 包括:正索引和负索引两部分,如下图所示,以a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]为例: python索引方式.jpg 二. P ...