
算法、数据结构心得
文章平均质量分 64
这里是算法、数据结构的个人总结
linkfqy
A link to FQY.
展开
-
整体二分小结
最近做了一些整体二分的题目,对此有一些体会,在此小结。一般的二分答案算法每次只能处理一个询问而整体二分是同时对所有询问进行二分的算法。一般来说,整体二分的思想如下:定义divide(L,R,S)divide(L,R,S)表示答案在[L,R][L,R]范围内的询问集合为SS往往会有一些事件对答案产生贡献考虑[L,mid][L,mid]中所有事件对每个询问的影响然后根据询问的限制,将所有询问分至S1,S原创 2017-10-06 14:00:42 · 735 阅读 · 0 评论 -
关于高斯消元
其实是很简单的一个算法,之前一直不会……主要思想如下:我们现在有n个关于未知数xi,(1≤i≤n)x_i,(1\le i\le n)的方程: ∑j=1na1,jxj=a1,n+1∑j=1na2,jxj=a2,n+1…∑j=1nan,jxj=an,n+1\sum_{j=1}^n a_{1,j}x_j=a_{1,n+1} \\\sum_{j=1}^n a_{2,j}x_j=a_{2,n+1} \\原创 2017-09-19 19:26:08 · 999 阅读 · 1 评论 -
【持续更新】莫比乌斯反演简明教程
前言开始学省选算法了……感觉莫比乌斯反演好厉害的样子,就先学习一下一入反演深似海……相关的东西太多了,以后会不定期更新前置技能莫比乌斯函数莫比乌斯函数μ(n)\mu(n)的定义如下:设n=pk11⋅pk22…pkmmn=p_1^{k_1}\cdot p_2^{k_2} \dots p_m^{k_m} μ(n)=⎧⎩⎨1(−1)m0n=1∏mi=1ki=1otherwise(ki>1)\begin原创 2017-11-30 21:09:53 · 2932 阅读 · 0 评论 -
边双联通分量小结+模板
为什么我之前都没学过……预备知识桥:如果去掉,图的联通块个数会增加的边DFS树:将一个图DFS遍历所得到的树非树边:不在DFS树上的边显然非树边只会存在于DFS树的点与祖先之间非树边不可能是桥边双联通分量:任意两点通过【不经过同一边】的路径可达的子图桥有了以上姿势,就可以找到一张无向图的所有桥了记录in[x]in[x]为x入栈的时间戳,low[x]low[x]为x可达的所有点中最小的in显然,DFS原创 2017-10-28 07:55:31 · 1683 阅读 · 0 评论 -
浅谈2-SAT问题
SAT及2-SATSAT是一类关于变量取值的问题 具体模型:有若干个变量,各变量之间有取值约束,判断是否有一个满足所有约束的可行解,或求出某个特殊解 特殊地,若所有变量的取值都只有两种可能,那么此问题被称为2-SAT问题2-SAT的解法首先是建图。 对于2-SAT问题,我们一般先观察题目条件 把它抽象成约束关系,再进行建图。 建图时,一个变量的两个取值视为两个不同的点。比如:a|ba|b为原创 2017-07-16 19:29:02 · 1804 阅读 · 1 评论 -
KMP算法及其应用
前言今天学习了一个新算法:KMP算法 其实很久以前学过早忘了 KMP算法是用于处理字串问题的算法。参考Matrix67的博客:KMP算法详解|Matrix67KMP算法的原理假设有字符串A和B,要求判断B是否是A的字串 其实就是对于每个i,求最大的j,使得Ai−j+1→i与B1→jA_{i-j+1\rightarrow i}与B_{1\rightarrow j}一一匹配 能匹配j指针就往后跳原创 2017-08-01 21:23:24 · 4068 阅读 · 0 评论 -
模拟退火与爬山算法
前言最近学习了一些元启发算法,感觉这些算法的原理都挺有趣的 结合了物理,生物学的现象 (不得不感叹一下前人的脑洞)爬山算法先来讲下爬山算法。考虑这样一个问题: 假设有一个函数 f(x)f(x)如何求它的最大值? 画出它的图像如下: 每次在当前位置的两侧判断是否比当前更高 就像爬山一样往高处爬,最终会到达一个较高的位置但是这通常不是整体最优解,而是局部最优解 像这样: 登山者到原创 2017-07-18 22:38:57 · 5973 阅读 · 4 评论 -
多项式与快速傅里叶变换
前言快速傅里叶变换(Fast Fourier Transform, FFT)是计算序列的离散傅里叶变换(DFT)或其逆变换(IDFT)的一种算法。一般用于快速计算多项式乘法。预备知识单位复数根n次单位复数根是满足ωn=1\omega ^n=1的复数ω\omega显然n次单位复数根恰好有n个根据复数的指数形式定义: eiu=cos(u)+i×sin(u)e^{iu}=cos(u)+i\times原创 2017-08-11 21:32:31 · 5432 阅读 · 5 评论 -
树分治-点分治
前言很久以前就学过树分治,但是掌握不熟练(其实是弃坑了) 所以现在重新拾起这个算法,终于填坑完成…… 发现还是挺简单的正文树分治,是用于统计树上路径的算法POJ1741就是一个很好的例子 下面会以此题为例,详细讲解树分治树分治分为两种:点分治与边分治 点分治:每次找一个点,分治所有以它的儿子为根的子树 边分治:每次找一条边,分治它连接的两个点为根的子树由于边分治容易被特殊数据卡,所以一般使原创 2017-07-10 21:29:15 · 3085 阅读 · 0 评论 -
详解差分约束系统
什么是差分约束系统?差分约束系统,是一类关于不等式组的线性规划问题 比如: 给出n个形如 a−b≤ca-b \le c的不等式,求一组任意解一般可以转化为最短路问题求解。差分约束系统的转化我们以 Xi−Yi≤ZiX_i-Y_i\le Z_i为例 观察发现,其实这个不等式与最短路问题中的“三角不等式”相似: Dist(i)+W(i,j)≥Dist(j)Dist(i)+W(i,j)\ge Dis原创 2017-07-25 22:51:47 · 1940 阅读 · 0 评论 -
C++ bitset使用教程
前言话说昨天考试有一道题目,可以用bitset艹过去 可是LZ并不会啊……于是只好打暴力…… 结果可想而知…… 于是LZ下定决心一定要把bitset学透 然后……就有了这篇blogbitset定义与初始化bitset是用于记录01串的容器 也就是bitset的每个元素只能为0/1用bitset之前别忘了:#include<bitset>以下是正确的定义方式:bitset<16> a; /原创 2017-07-06 19:34:55 · 2475 阅读 · 3 评论 -
C++ STL nth_element原理与应用
LZ最近的考试中,某题可以通过调用nth_element()来水过70%的数据 但是LZ并不会啊(历史总是惊人的相似) 于是就有了这篇blog在编写代码时,有时会有“在一个无序表中快速得到第K小的元素”的需求 而直接排序 不能水过一些测试点 时间不能承受 于是STL的algorithm头文件就给我们提供了nth_element()这样的部分排序函数调用的正确姿势是这样的:nth_elemen原创 2017-07-09 08:57:23 · 10714 阅读 · 3 评论 -
浅谈上下界网络流
背景最近一直在做这类题目…… 感觉题目变化还是挺多的 就在这里总结一下好了……首先Orz Lynstery 本文参考博客:有上下界的网络流学习笔记——by liu_runda正文上下界网络流,显然就是对每条边有上下界流量限制的网络流问题 众人:这不废话嘛 对于上下界网络流问题,最重要的思想是“转化” 因为学习后你会发现:处理每一种情形都是要由前一种更为简单的情形转化过来,然后用同样的方法原创 2017-07-07 21:18:29 · 4995 阅读 · 4 评论 -
莫队算法
【前言】莫队算法(Mo’s algorithm)是由莫涛队长发明的,一种处理区间问题的离线算法,由于其代码简便,常数巨小,适合各种打暴力。另:关于带修改的莫队,可以看这里【做法】前提:如果已知区间[L,R]的答案,可以很快(log或常数级别)地得到区间[L±1,R±1]的答案。 对于区间询问[L,R],我们可以先读进来所有询问,按照某种顺序依次处理(线性移动L,R端点),就可以得到所有询问的答案。原创 2017-04-26 21:52:41 · 1667 阅读 · 1 评论 -
带修改的莫队算法
【前言】普通的莫队算法固然强大,但是不能支持修改操作 于是就有了带修改莫队这种神奇的东西。【做法】普通的莫队可以看这里 那么对于询问的结构体,可以多记录一个信息ti 表示到这个询问为止最后做的修改的编号至于排序么……与普通莫队类似,只是把ti作为第3个关键字 (当R在同一块的,就按ti排序)处理时,要使当前区间,修改的指针一起动 (每次线性移动修改指针(修改/撤销),使得前ti个原创 2017-04-29 21:22:32 · 2153 阅读 · 1 评论 -
同余及其性质
把数论里的一些零散的知识总结一下……【同余】a模b,即a除以b的余数,记做”a mod b”或”a%b”。 同余,用符号≡表示,若a%m=b%m则称a与b关于m同余,记做”a≡b (mod m)” 本文中,a与b的最大公约数记为(a,b),最小公倍数记为[a,b],a能整除b记为a|b【同余的几个性质】性质1:a≡a(mod m),(反身性) 性质2:若a≡b(mod m),那么b≡a(mod原创 2017-02-17 10:42:26 · 5063 阅读 · 1 评论 -
浅谈逆元
【逆元的定义】对于任意正整数a,m,若ax≡1 (mod m),则这个关于x的同余方程的最小正整数解x为“a模m的逆元”。【逆元的应用】常常会遇到这种题目:题目中运算的数据比较大,为了避免使用高精度,会要求选手输出答案mod p的结果,一般p是大小合适的质数。这样就可以利用同余的原理,使得每次运算结果都小于p,避免了高精度的使用。 显然,上述方法对于+、-、*运算还是比较方便的,但是如果需要用到原创 2017-02-17 10:51:24 · 615 阅读 · 0 评论 -
欧拉函数
【欧拉函数】欧拉函数是数论中十分基础的一个函数,其意为:对于一个正整数n,小于n的与n互质的数的个数为n的欧拉函数,记作φ(n)或phi(n)。 另外,小于n的与n互质的所有数构成的集合Zn=为模n的简化剩余系。【欧拉函数的性质】欧拉函数是积性函数:对于互质的两个正整数n,m有φ(nm)= φ(n)* φ(m) 显然,对于一个质数p,有φ(p)=p-1【通项公式】根据以上两个性质,我们可以推导出原创 2017-02-17 10:58:43 · 873 阅读 · 1 评论 -
欧拉定理
总结写在Word上…… Word里面的公式不能搞到csdn上,只能以图片的形式,大家将就着看……原创 2017-02-17 11:03:14 · 721 阅读 · 0 评论 -
欧几里得算法及其扩展形式
【欧几里得算法】欧几里得算法(Euclid’s algorithm),又称辗转相除法。由欧几里得在大约两千多年前提出,该算法能够快速求得正整数a,b的最大公约数gcd(a,b)。 本文仅讨论非负数情况下的问题。【算法描述】我们一般以递归形式实现欧几里得算法:int gcd(intx,int y){ if (!y) return x; return gcd(y,x%y);}【证明】原创 2017-02-17 11:10:27 · 848 阅读 · 0 评论 -
关于素数筛法的一点讨论
前言在数论领域,解决问题时经常会有得到素数的需求 如何快速得到一定范围内的所有素数,就成了人们一直追求的问题 这里列举一些素数筛法,也许会有帮助埃氏筛法(Sieve of Eratosthenes)笔者在最早接触数论时,就学到的算法 思路比较简单: 对于每个素数,都枚举其倍数打上标记 那么没打过标记的就都是素数了 示例程序:原创 2017-06-28 19:45:07 · 1047 阅读 · 3 评论 -
斐波那契数列的性质
斐波那契(Fibonacci)数列: fi=⎧⎩⎨01fi−1+fi−2i=0i=1i≥2 f_i =\begin{cases}0 & \text{i=0} \\1 & \text{i=1} \\f_{i-1}+f_{i-2} & \text{i≥2}\end{cases} 这个东西貌似是一种很神奇的存在…… 这里列举一些性质: 1.f1+f2+……+fn=fn+2−1f原创 2017-06-28 20:39:34 · 2877 阅读 · 5 评论 -
凸包——Andrew算法
什么是凸包?凸包的定义如下: 在一个点集D中,按一定顺序选取子集Q 使得Q中所有点顺次连接所构成的封闭凸多边形包住D中所有点可以形象地理解为:有许多个钉子钉在平面上,用一根牛皮筋把所有点包住 如下图: 常用算法凸包问题的一般解法有:Graham算法、Melkman算法、Andrew算法等 由于Andrew算法代码简便,效率比较高,笔者更推荐使用Andrew算法Andrew算法是Graham原创 2017-06-04 20:52:15 · 3523 阅读 · 1 评论 -
Trie树(字典树)
何为Trie树?先容我吐槽一下这个数据结构的名字…… /ˈtriː/?/ˈtraɪ/?傻傻分不清楚Trie树,又称字典树,是一种树形数据结构 被广泛用于字符串的统计Trie树的构造Trie树节点的每个儿子都代表一个字母 那么就可以用某节点到根的路径来表示一个字符串 如下图: (这颗Trie树保存了8个字符串:”A”, “to”, “tea”, “ted”, “ten”, “i”, “i原创 2017-06-11 21:39:28 · 1003 阅读 · 3 评论 -
Manacher算法——最长回文子串
今天抽空学习了下这个简单的算法……背景Manacher用于求最长回文子串问题 是最简单也是最为常用的算法首先,我们需要考虑回文串长度的奇偶 会发现长度为奇时,回文串有一个对称点 长度为偶时则不然 为了方便解题,我们需要对原字符串进行预处理:orzLynstery#o#r#z#L#y#n#s#t#e#r#y#可以发现,每个空隙中填充’#’后,回文子串长度一定为奇做法定义f[i]f[i]表示原创 2017-06-13 15:13:39 · 932 阅读 · 1 评论 -
A*-总结
【前言】A*是被广泛运用于实际生活的一种搜索算法,在OI中也非常实用。【A*的原理】我们来回想一下BFS的原理: 每次从队首取一个状态,用其扩展出新的状态并放入队尾。 那么这个队列是没有优先级的A*其实与BFS类似,只是给每个状态定义了估价函数f(x) 用于估计此状态最终到达目标状态的总代价。 只需要让代价小的先扩展,就能尽可能地将复杂度降到最低。此时估价函数f(x)的选取就很重要了 因为原创 2017-05-26 08:07:22 · 706 阅读 · 1 评论 -
斜率优化DP 与数形结合思想
前言最近才入了DP优化的大坑…… 发现斜率优化DP还是很有用的 下面会结合一道例题,同时讲解斜率优化DP正文先看一下例题:HDU3507 题目大意:有一串数列,要把它分割成若干段 每一段的代价是 这一段所有数的和 的平方 再加上常数M 求最小的代价和。DP很好推啊,f[i]f[i]表示前i个数字的最小代价和 f[i]=Min{f[j]+(s[i]−s[j])2}+Mf[i]=Min\{f原创 2017-06-05 20:18:43 · 1586 阅读 · 2 评论 -
树链剖分-总结
【树链剖分是啥?】树链剖分是用于将树上操作转化为序列操作的一种算法。在信息学竞赛中有着广泛的应用。 比如:给定一棵树以及各点的权值,每次操作给出两个点,把这两点之间路径上的所有点的权值改变或者求和。 这种题目就是典型的树链剖分,转化成序列操作之后用线段树维护即可。【概念】我们把子树x的节点个数记为siz[x]。 那么对于任意节点i,定义它的儿子中siz[]最大的为i的“重儿子”(H_son[i原创 2017-04-08 18:38:41 · 1346 阅读 · 3 评论 -
网络流-最大流
【前言】网络流作为一个经典问题,在OI及实际生活中有着广泛的应用,值得我们仔细研究。【何为网络流?】网络流,是一种资源调配问题,如下图(以下图片均来自网络): 其中,S表示网络流中的源点,是资源的唯一出发点。 T表示网络流中的终点,是各种资源的目的地。 正如水管有粗细之分,道路有宽窄之分, 网络流中的每条边(这里称为弧)都有一个容量cap,表示单位时间最多能通过的资源量。 同时,每条弧原创 2017-05-15 21:12:15 · 2365 阅读 · 2 评论 -
左偏树-总结
【左偏树】左偏树是一种可并堆,也是一种优先队列容器。它除了支持查找最小值、删除最小值、插入值外,还支持优先队列不必需的合并(merge)操作。且左偏树的编程复杂度低,效率较高,适合竞赛中使用。【左偏树的性质】我们一般以存二叉树的方法来描述左偏树:对于每个节点,记录其左右儿子(无儿子的指向空节点0),这个节点的键值,以及节点的距离(距离的定义下面会讲)。struct node{ int l,r原创 2017-02-15 21:15:18 · 1783 阅读 · 1 评论 -
Treap-总结
【前(fei)言(hua)】对于BST,相信大家都很熟悉了。BST系列的数据结构功能都比较强大,但是朴素BST的效率实在不敢恭维,非常容易被卡。今天介绍的Treap是BST的加强版,可以有效防止被卡。【Treap的性质】BST为什么这么容易卡呢?究其原因,其实是BST不太平衡导致的。所谓平衡,就是要让BST的左右两棵子树深度尽量相同,这样在操作时就不会往下查找过多的次数。 于是,我们可以在Tree原创 2017-03-05 15:45:22 · 1681 阅读 · 1 评论 -
Splay-总结
【前言】Splay Tree,又名伸展树,是OI中应用非常广泛的一种数据结构。相比其他BST,Splay的效率还是不错的。我们一般用Splay维护一个序列。【操作】Splay有以下几个基本操作:1.rot旋转 这个不用我多说了,平衡树中很常见的操作2.splay 伸展 splay(x,k)操作的目的是:从子树(子序列)x中找到第k个,并通过旋转的方式,将其弄到子树的根上。 这里就不得不提一下S原创 2017-04-02 13:19:04 · 1203 阅读 · 1 评论 -
树状数组区间修改+查询
【前言】树状数组可以处理单点修改,区间求和的操作,这里就不再赘述了。现在,我们要考虑用树状数组实现区间加,区间求和的操作。由于树状数组常数较小,代码简短,可以在一些场合代替线段树。【实现】首先明确一下,query(c,i)表示求c数组的前缀和。定义要维护的序列为a[],对a[]进行一次差分,得到c[]。 即c[i]=a[i]-a[i-1],显然c[1]+c[2]+……+c[i]=a[i]如何维护c原创 2017-04-07 18:20:39 · 919 阅读 · 1 评论 -
主席树/函数式线段树/可持久化线段树
【前言】主席树、函数式线段树、可持久化线段树 这三者其实是一个东西…… 它的作用十分显然,就是访问线段树的历史版本……【实现】假设我们要对线段树进行Q次插入操作,如何(随机)访问第i次操作后的线段树?我们当然可以对每个状态都造一棵完整的线段树,但是显然会MLE啊,怎么办? 观察可以发现,线段树的插入操作每次只会更新logN个节点,其他节点都不会变 于是我们可以利用前一次操作的状态,避免重复构原创 2017-04-15 11:10:41 · 2439 阅读 · 1 评论 -
非旋转Treap-总结
【前言】 非旋转Treap,又称FHQ_Treap,函数式Treap。由神犇FHQ首先提出(OrzOrzOrz)。由于使用了函数式编程的思想,非旋转Treap可以实现可持久化。 此外,非旋转Treap的大多数操作都基于分裂与合并,所以代码简短精炼,非常适合OIer食用。 【操作】 就讲讲分裂与合并好了……其他都是可以用脚趾头想出来的。分裂(split) 对于一棵Treap,我们把它分为ke原创 2017-04-18 19:58:03 · 2612 阅读 · 1 评论