- 博客(744)
- 资源 (1)
- 收藏
- 关注
原创 后缀数组
后缀数组 后缀数组就是把一个文本串的所有后缀按字典序从小到大排放的数组。详细介绍见刘汝佳《算法竞赛训练指南》。 AC自动机可以处理多模板的文本匹配问题,而后缀数组也可以处理多模板的文本匹配问题。那么它们有什么区别呢? AC自动机需要事先知道所有的模板,然后对于一个(在线输入的)文本串进行多模板匹配,也就是说模板一定要全部事先知道,需要匹配
2015-03-31 00:46:04 3031
原创 AC自动机
AC自动机 直接学AC自动机比较难理解,强烈建议先学完KMP和字典树并进行一定的练习后,对于失配指针和字典树构造有一定理解后再来学AC自动机的内容。有关AC自动机的详细介绍可见刘汝佳的《算法竞赛入门经典训练指南》P214.给你一个字典(包含n个不重复的单词),然后给你一串连续的字符串文本(长为len),问你该文本里面的哪些位置正好出现了字典中的某一个或某几个单词?输出这些位
2015-03-29 22:09:50 3190
原创 字典树Trie
字典树Trie 字典树又叫单词查找树(Trie)或前缀树(可见刘汝佳《算法竞赛入门经典训练指南》P208)。顾名思义它是与单词的前缀相关的。给你一个单词和一个字典构成的字典树,你可以在O(m)(m为所给单词的长度)时间内判断出该单词是否属于字典。但是如果你用KMP或其他暴力方法,你至少需要把字典中所有单词都遍历一遍。下图是一个具有单词abc,abcd,b,bcd,efg,hi
2015-03-27 11:01:35 2486 2
原创 KMP算法
KMP算法 KMP算法求出ex[i]数组,ex[i]数组表示主串S中以第i个字符(也即S[i-1]位置)为尾字符的后缀与模式串T的前缀的最长公共部分。 KMP模板中,字符都是从下标0开始存放的,直到m-1位置。假设有两个串S和T,其中T为模板串,S为主串。KMP其实本质是用来看S中每个i位置的后缀最多能与T的多长的前缀匹配的算法。即前缀匹配后缀的算法。进行模式串
2015-03-26 10:33:36 2261 9
原创 线段树
线段树注意:线段树维护的元素 与线段树的节点不一样。线段树整体维护的是从1到n下标的元素(当然也可以维护0到n-1号元素或者其他任意一个区间的元素)但是拥有1到大约3*n的树节点,每个树节点维护一段[L,R]的区间内所有的元素信息(没有0号树节点,因为如果你要指定0号树节点为根的话,那么i号树节点的左右儿子就不是i*2节点和i*2+1节点了)。而树节点中每个节点i都有它需要维护的区间[
2015-03-20 11:04:33 3961
原创 RMQ(Range MinimumQuery)问题
RMQ(Range MinimumQuery)问题 有关RMQ的详细介绍可见刘汝佳《算法竞赛入门经典训练指南》P197页 RMQ问题可以解决对于一个整数数组(当然也可以是其他可比较大小的元素类型)的任意区间[L, R]查询最值时,以O(1)时间复杂度回答询问。其实它就是一种数据压缩的思想。 RMQ能在经过O(nlogn)的时间预处理后,做
2015-03-15 15:43:24 1380
原创 树状数组
树状数组关于树状数组的详细介绍可见刘汝佳《算法竞赛入门经典:训练指南》 对于一个n元素的数组A[n],可执行如下操作: Add(I, d):让A[i]变成A[i]+d。 Query(L, R):返回A[L]+A[L+1]+…+A[R]。 注意:树状数组只能计算A[1]开始的和,A[0]这个元素是不能用的。上面操作复杂度都是
2015-03-14 21:35:27 2414
原创 并查集
并查集 并查集是一种数据结构,一般它处理的是图(其实是解决无向图的)的连通分量问题,但是当并查集的根节点可以维护更多的信息时,并查集可以解决范围更广的基于无向图连通分量的问题。做了这么多并查集的题目后,我感觉并查集就是解决有关物与物之间的关系问题的数据结构且这种关系还必须是可传递的关系,所以一般遇到这种问题可以先尝试用并查集解决。 并查集的基
2015-03-08 11:00:28 2655 6
原创 二分图判定
二分图判定 二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。 二分图的另一种等价的说法是,可以把每个节点着以黑色和白色之一,使得每条边的两个端点颜色不同.不难发现,
2014-06-14 17:31:47 1919
原创 BFS学习总结
BFS学习总结 给你一个n*m的网格迷宫,迷宫中有些格子不能走,其他的格子都能走。然后给你起点与终点,问你从起点走到终点最少需要多少步? 上面的问题就是一个典型的BFS问题,对于这类问题来说,只要你掌握了这类问题的关键思想,其实他们都是可以用类似的思路来做的。建议先做两道BFS简单题,体会一下。 你可以把BFS问题想象成:从一个父亲(起点
2015-04-15 23:53:09 4256 2
原创 网络流
网络流 网络流问题的详细介绍可以看刘汝佳>和>相关部分。注意:下面的网络流模板里面考虑的都是有向图,如果要处理无向图,那么对于无向图的每条边,你需要再图上添加两个方向的边各一条且流量费用相同。 熟练模板并不是问题,问题是如何把实际的问题转化为网络流的问题来解决。直接给出最大流的模板://最大流模板,可处理重边//且节点编号从1到n,边编号从0到m
2015-04-13 21:29:12 2890
原创 二分图匹配
二分图匹配 给定一个二分图G(无向图),在G的一个子图M中,M的边集中的任意两条边都不依附于同一个顶点,则称M是一个匹配. 选择这样的边数最大的子集称为图的最大匹配问题(maximal matchingproblem) 如果一个匹配中,图中的每个顶点都和图中某条边相关联,则称此匹配为完全匹配,也称作完备匹配。 如果该二分图的每条边
2015-04-11 23:10:56 2223
原创 最小生成树
最小生成树 一个有 n 个结点的连通图的最小生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的权值总和最小的边。刘汝佳>P343详细介绍了最小生成树相关的知识。 下面直接给出Kruskal算法的模板:#include#include#include#include#includeusing namespace std
2015-04-05 01:20:54 2232 2
原创 Bellman_Ford算法
Bellman_Ford算法 Bellman_Ford算法也是求单源最短路径的算法,但是它能算带负权边的图的最短路径(对于带负圈的图就无能为力),且可以判断当前图是否带有负圈。它的时间复杂度是O(n*m),其中n为点数,m为边数。 Bellman_Ford算法为什么能求得单源最短路径呢?因为它一共松弛n-1轮,每轮遍历了所有的边,所以它每轮至少要生成一个点的
2015-04-04 22:30:20 1738
原创 Floyd算法
Floyd算法 Floyd算法又称为插点法,是一种用于寻找给定的加权图中多源点之间最短路径的算法。该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名。 注意:由下面的练习可以看出,其实很多题目不是直接问你floyd怎么求最短路径,而是要你利用floyd的动态规划思想解决类似floyd的问题。 Floy
2015-04-04 19:14:04 2554
原创 Dijkstra单源最短路径
Dijkstra单源最短路径 给定一个带权有向图G=(V,E) ,其中每条边的权是一个非负实数。另外,还给定 V 中的一个顶点,称为源。现在我们要计算从源到所有其他各顶点的最短路径长度。这里的长度是指路上各边权之和。这个问题通常称为单源最短路径问题。 下面给出两个计算单源最短路径的模板。Dijkstra_简化版:时间复杂度O(n^2),不可处理重边图
2015-04-04 14:14:25 2233 1
原创 2-SAT问题
2-SAT问题 现有一个由N个布尔值组成的序列A,给出一些限制关系,比如A[x]AND A[y]=0、A[x] OR A[y] OR A[z]=1等,要确定A[0..N-1]的值,使得其满足所有限制关系。这个称为SAT问题,特别的,若每种限制关系中最多只对两个元素进行限制,则称为2-SAT问题。 由于在2-SAT问题中,最多只对两个元素进行限制,所以可能的限制关
2015-04-03 19:17:37 1519 1
原创 有向图的强连通分量
有向图的强连通分量 有向图强连通分量在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。有向图的极大强连通子图,称为强连通分量(strongly connected components)。
2015-04-03 11:10:25 2564
原创 无向图的双连通分量
无向图的双连通分量 点-双连通图:一个连通的无向图内部没有割点,那么该图是点-双连通图。 注意:孤立点,以及两点一边这两种图都是点-双连通的。因为它们都是内部无割点。 边-双连通图:一个连通的无向图内部没有桥,那么该图就是边-双连通的。 注意:孤立点是边-双连通的,但是两点一边不是边-双连通的。 由上面定义可
2015-04-02 18:45:47 3963
原创 无向图求割顶与桥
无向图求割顶与桥 对于无向图G,如果删除某个点u后,连通分量数目增加,称u为图的关节点或割顶。对于连通图,割顶就是删除之后使图不再连通的点。如果删除边(u,v)一条边,就可以让连通图变成不连通的,那么边(u,v)是桥。 具体的概念和定义比较多,在刘汝佳训练指南>>P312-314页都有详细的介绍。 下面来写求无向图割顶和桥的DFS函数.我们令p
2015-04-02 14:14:22 2296 3
原创 拓扑排序
拓扑排序 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。 一个有向图无法拓扑排序时只有一种情况:该有向图中存在环。下面给出简单的判定有向图是否可拓扑排序的代码:题意:给你一个N点和M条有向边的图,问
2015-04-01 16:52:21 1663 1
原创 欧拉图详解
欧拉图详解 通过图(无向图或有向图)中所有边一次且仅一次行遍图中所有顶点的通路称为欧拉通路,通过图中所有边一次且仅一次行遍所有顶点的回路称为欧拉回路。具有欧拉回路的图称为欧拉图(Euler Graph),具有欧拉通路而无欧拉回路的图称为半欧拉图。 1定义 欧拉通路(Euler tour)——通过图中每条边一次且仅一次,并且过每一顶点的通路。
2015-04-01 13:18:37 11413
原创 Treap
Treap Treap是一种动态平衡的BST(Binary Search Tree),它每个节点拥有键值和优先级两种属性。对于键值而言,它是一颗排序二叉树。对于优先级而言,这棵树是堆(优先级最高的是根节点)。可以证明Treap中插入,删除和查找的期望时间复杂度均为O(logn)。关于Treap的更多介绍,可见刘汝佳《训练指南》P230。一般我们用Treap就是用来替代平衡二叉
2015-03-31 14:37:40 2788
原创 C++ Primer学习总结 第15章 面向对象程序设计
第15章 面向对象程序设计1. 构造基类和派生类。其中A类是基类,B类是派生类。派生类的构造函数必须重新写过,不能继承。(因为毕竟两个类的类名都不一样,不可能构造函数继承)只继承其他的成员函数和成员变量。派生类可以覆盖基类的虚函数,但是也可以选择不覆盖(即直接使用父类的函数版本)比例A类的print_1()虚函数就没有被覆盖。基类的静态成员:如果基类有一个静态成员
2015-03-10 09:15:03 1307 2
原创 C++ Primer学习总结 第14章 操作重载与类型转换
第14章 操作重载与类型转换1. 可以直接调用重载的运算符函数.但是如果对于一个运算符比如+号,既有重载的成员函数,又有重载的非成员函数,那么此时如果直接使用+号,那么就会出现错误. 因为编译器不知道要调用那个运算符. 2. 逗号,运算符逻辑与&&运算符逻辑或||运算符不建议重载.因为上述3种运算符本身是有求值顺序和短路求值特性
2015-03-10 09:08:08 1316
原创 C++ Primer学习总结 第13章 拷贝控制
第13章 拷贝控制1. 什么是拷贝构造函数? P440如果一个类的构造函数的第一个参数是自己类类型的引用, 且所有其他参数都有默认值, 那么这就是一个拷贝构造函数. 2. 拷贝初始化和直接初始化. P441如果初始化的时候使用等号”=”来初始化一个对象, 那么就是拷贝初始化.相反, 如果初始化时, 没有用等号”=”, 那么就是直接初始化.
2015-03-09 10:33:57 2064 2
原创 C++ Primer学习总结 第12章 动态内存
第12章 动态内存1. 申请并使用shared_ptr. P400 2. shared_ptr计数. P402赋值, 拷贝, 向函数传递一个智能指针, 或函数返回一个智能指针都会增加当前智能指针的计数. 3. 不同对象间利用智能指针共享数据的例子. 4. 使用new来动态申请内存. P407默认情况下
2015-03-09 10:21:58 1252
原创 C++ Primer学习总结 第11章 关联容器
第11章 关联容器1. 使用map的简单例子:运行结果为: 2. 初始化map和set: 3. set与multiset的区别: 4. 使用map和set时,其元素类型必须是定义了严格弱序的(即定义了号比较的),如果元素类型没有定义 5. pair类型:pair是一个用来生成特定类型的模板. pa
2015-03-09 10:14:11 1266
原创 C++ Primer学习总结 第10章 泛型算法
第10章 泛型算法1. find()泛型算法使用示例: 2. 只读算法accumulate:对所给范围的元素求和并返回. 注意accumulate的第3个参数决定着它的返回类型. 即如果第3个参数是double,就算迭代器里都是int,最终还是返回double类型的数. 3. 只读算法equal:比较前两个迭代器表示范围的所有元素是
2015-03-09 10:07:33 1114
原创 C++ Primer学习总结 第9章 顺序容器
第9章 顺序容器1. 顺序容器如果有一个只需要容器大小参数的默认构造函数,该函数使用的是元素的默认构造函数来构造每个元素对象,如果该容器的元素没有默认构造函数,那么就不能使用这个容器的该构造函数P294: 2. 容器进行拷贝初始化时,两个容器的元素必须同类型.但是如果列表初始化,或迭代器范围初始化容器,那么只要求列表中元素或迭代器所指元素可以转化为容
2015-03-09 09:50:06 1026 1
原创 C++ Primer学习总结 第8章 IO库
第8章 IO库1. IO类继承关系:2. 查询iostream流状态P280-281V是一个int,当我们输入1, ‘r’,或Ctrl+z 时的输出分别如下:cin.clear()可以清楚所有的错误位,使good()返回true. 3. fstream对文件的读写P284初始创建读入和写出fstream对
2015-03-07 01:11:00 1472
原创 C++ Primer学习总结 第7章 类
第7章 类1. 引入const成员函数(C++ Primer P231-232)C++类的常量对象是无法调用非const成员函数的,如果想让常量对象调用某个成员函数,必须声明成const: 2. 一个类的尾后const成员函数如果返回*this,那么其返回类型必然是const类名 & 前面这个const是不能少的.否则无法通过编译.
2015-03-07 01:02:27 2035 1
原创 C++ Primer学习总结 第6章 函数
第6章 函数1. 函数最外层作用域中的局部变量不能使用与函数形参一样的名字,因为它们属于同一个作用域范围. 2. 局部静态变量的生命周期: 在整个程序的执行路径第一次经过对象定义语句时初始化,并且直到整个程序终止时才被销毁,在此期间即使对象所在函数结束执行也不会对它有影响. 3. 如果重载的函数的参数只有顶层const区别,那么
2015-03-07 00:48:42 1898 1
原创 C++ Primer学习总结 第5章 语句
第5章 语句1. switch中的case标签必须是整型常量表达式,不能是变量也不能是非整型:注意第二个case 3.14 在C++11中没错误可以执行,但是在C++98中编译不通过. 2. switch语句的case语句初始化了一个变量时要注意:Case语句不能跳过变量的初始化,可以跳过变量的定义。 3. 范围for语
2015-03-07 00:24:03 1286
原创 C++ Primer学习总结 第4章 表达式
第4章 表达式1. decltype作用于左值对象时,返回的是该对象的引用类型. 作用于右值对象时,返回的是该对象的类型.2. 求值顺序.C++中只有&& || ?: 和, 4种运算符是先左后右求值的. 3. 一元正负号运算符作用于数值:会提升当前数值的类型,比如short变成int型 4.
2015-03-07 00:17:44 1459
原创 C++ Primer学习总结 第3章 字符串,向量和数组
第3章 字符串,向量和数组1. 如何用string读取一整行内容?用getline(cin,s)即可. 当然getline()也可以用来作为while循环读取输入的判断条件. 2. string与字符串字面值,字符字面值相加由于+法是从左向右运算的,所以只要保证每次两个值相加时,+号左右两边至少有一个是string就行. 3. string
2015-03-05 20:22:46 1248 1
原创 C++ Primer学习总结 第1-2章 变量和基本类型
第1-2章 变量和基本类型1.下面这个语句在C++98和C++11中的输出结果不同.C++98结果:(如果想要更高的精度,可以用%.9lf,输出9位有效数字)C++11结果:结论:printf的%lf在C++11中表示longdouble,所以用中%f就可以输出float和double类型.而printf在C++98中可以用%lf正确
2015-03-05 20:12:56 1450 1
原创 HDU 2012 素数判定(素数)
HDU 2012 素数判定(素数)http://acm.hdu.edu.cn/showproblem.php?pid=2012题意:水题一枚 对于表达式n^2+n+41,当n在(x,y)范围内取整数值时(包括x,y)(-39<=x<y<=50),判定该表达式的值是否都为素数。分析: 本题的数据范围很小,求出表达式在-39到50内的所有可能值可以得到下面的数:1523 1447 13731301 1231 1163 1097 1033 971 911853 797 7
2014-11-16 15:50:00 2494
原创 HDU 1431 素数回文(回文素数)
HDU 1431 素数回文(回文素数)http://acm.hdu.edu.cn/showproblem.php?pid=1431题意: 给你两个整数a,b。(5 <= a < b <= 100,000,000)要你按顺序输出[a,b]区间内的所有回文素数。分析: 定理:如果一个数是回文且有偶数位,那么它能被11整除。 根据上面定理我们可知我们只需要找到区间[2,1000W)内的素数即可。(想想为什么)上面b的范围直接缩小了10倍。 剩下的工作就是用
2014-11-16 15:26:25 1606
原创 HDU 1262 寻找素数对(素数)
HDU 1262 寻找素数对(素数)http://acm.hdu.edu.cn/showproblem.php?pid=1262题意: 哥德巴赫猜想大家都知道一点吧.我们现在不是想证明这个结论,而是想在程序语言内部能够表示的数集中,任意取出一个偶数,来寻找两个素数,使得其和等于该偶数.做好了这件实事,就能说明这个猜想是成立的.由于可以有不同的素数对来表示同一个偶数,所以专门要求所寻找的素数对是两个值最相近的.分析:显然先用筛选法求出10000以内的所有素数,然后对于给定的数X。 一定
2014-11-16 14:51:13 1618
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人