算法总结
文章平均质量分 76
omsobliga
这个作者很懒,什么都没留下…
展开
-
素数专题
#include #include using namespace std;const int nMax = 10000000;int isPrime[nMax];int prime[nMax];int factor[nMax];int len;void f1()//朴素筛选{ int n;//求[1, n]之间的素数 scanf("%d", &n); len = 0原创 2012-08-14 16:36:47 · 833 阅读 · 1 评论 -
米勒-拉宾算法
米勒-拉宾算法:快速判断一个数是不是素数需要用到的定理:最小费马定理:如果n是素数,则(a ^ (n - 1)) % n恒等于1。快速模取幂米勒-拉宾算法就是结合上面两种,通过不断判断fmod(a, n - 1, n)的值是否为1来判断。这是一个概率算法,如果为1,不一定为素数,不为1,则必定是合数。循环判断多次就会让概率变得极为的小。算法模板:#include u原创 2012-08-06 11:20:32 · 4806 阅读 · 2 评论 -
分治+贪心
《算法竞赛入门经典》---高效算法设计,作者的编辑思路,是首先介绍了算法的效率分析。 其中规模与运算量的对应关系大致为:然后谈到归并排序、快速排序和二分查找,推荐对 [ )的使用,然后谈到二分查找中的集中具体情况bsearch,lower_bound(找上界(即:第一个元素下标)),upper_bound(找下界(最后一个元素的下一个下标)),然后介绍分治法,分治法三步走:划分问题:把原创 2012-05-14 23:35:05 · 748 阅读 · 0 评论 -
线段树
谈对线段树的理解:线段树又称(区间树),实质就是:树中节点可表示一个区间,所以称为区间树更合适一些。节点中可添加适当的数据来实现相应的一些操作,每个节点的数据都是建立在左子树和右子树之上。这样做的目的使查找效率从O(n)降为O(log(n))线段树的模型:适用与使用线段树解决的问题:某些数据需要按区间进行区分,按区间进行修改,而且需要多次按区间进行查询。例如多次查询第k小元素,原创 2012-04-20 18:17:59 · 781 阅读 · 0 评论 -
后缀数组小结
初学后缀数组://后缀数组模板int wa[maxn],wb[maxn],wv[maxn],ws[maxn];//这些都是需要用到的中间变量int cmp(int *r,int a,int b,int l){ return r[a]==r[b]&&r[a+l]==r[b+l];}void da(int *r,int *sa,int n,int m)//这里的n应该是字符串长原创 2012-08-11 16:29:27 · 654 阅读 · 0 评论 -
KMP(单模式匹配)
KMP处理问题:①单字符串匹配,返回匹配地址、求出匹配总次数②求循环元,t = len - next[len]简单心得:①next[]数组的有效范围是[0,len],len的时候,next[]为有效值②只需要记住next[0] = -1,next[1] = 0,这两个条件就可以写出求next[]的函数③匹配过程只需要O(N),所以i的值不需要回归。这里曾经纠结很久,matc原创 2012-04-09 15:14:44 · 553 阅读 · 0 评论 -
AC自动机(多模式匹配)
AC自动机主要解决的问题:多模式匹配(KMP则属于单模式匹配),n个单词在m个字符的文章中,出现过多少次。主要分三步:构建trie树、构建失败指针、寻找匹配个数Trie树:又称字典树、单词查找树,是一种树形结构,用于保存大量的字符串。它的优点是:利用字符串的公共前缀来节约存储空间。具体参见:http://www.cppblog.com/abilitytao/archive/2009原创 2012-08-02 19:43:39 · 817 阅读 · 0 评论 -
Trie树
一、Trie树,又叫字典树,就是将字典存入到树中,方便进行单词匹配。其实实现起来很简单,模版如下://动态分配内存struct Trie{ int count; Trie *next[26]; Trie() { count = 0; memset(next, 0, sizeof(next)); }};void buildTrie(Trie *root, cha原创 2012-09-03 21:08:32 · 511 阅读 · 0 评论 -
动态规划总结
学习动态规划有一段时间了,总结一下,开始新的算法一、为什么要使用动态规划?当回溯效率太低的时候,动态规划是个不错的选择,因为它是不断建立在最优状态上的递推,得出最终结果。二、动态规划两大标志:1)最优子结构:一个问题的最优解包含子问题的最优解,这个性质被称为最优子结构2)重叠子问题:不同问题包含相同的子问题。即:原问题不断分解成同样的子问题,而不是产生新的问题。重点:重叠子原创 2012-05-02 21:26:44 · 832 阅读 · 0 评论 -
最短路经问题
Prim算法:主要处理问题:最小生成树问题。算法思想:V表示所有节点集合,首先s进入集合U,然后找出集合U与剩余节点V-U中最小权值的边[u,v],将v加入集合U,直到U==V截至时间复杂度:相对与Kruskal需要多次排序,>>O(E)Kruskal算法:推荐主要处理问题:最小生成树问题。算法思想:对所有边按照权值进行排序,然后使用并查集,将所有节点加入到集合中。原创 2012-09-12 09:41:36 · 1059 阅读 · 2 评论 -
[转] ACM的你伤不起!!!
劳资六年前开始搞ACM啊!!!!!!!!!! 从此踏上了尼玛不归路啊!!!!!!!!!!!! 谁特么跟劳资讲算法是程序设计的核心啊!!!!!! 尼玛除了面试题就没见过用算法的地方啊!!!!!! 谁再跟劳资讲算法之美算法的力量,劳资一本算法导论拍死你啊!!!!!!!! 那是搞ACM的入门书啊!!!!特么的入门书就一千多页啊!!!!!!! 还没有习题答案啊,学完了你特么都不知道转载 2012-09-09 18:56:57 · 1917 阅读 · 0 评论 -
数论初步
一、辗转相除法(又称欧几里德算法):gcd(a, b) = gcd(b, a % b);int gcd(int a, int b){ return b == 0 ? a : a % b;}另外:最小公倍数 * 最大公约数 == 两数之积二、筛选法构造素数表int visit[nMax];int prime[nMax];int getPrime(int n)//原创 2012-05-18 23:30:06 · 864 阅读 · 0 评论 -
快速幂取模
对于a^b%c问题,当a和b都很大时的处理方法。首先介绍一个定理:a*b%c=(a%c)*b%c ;方案一:a^b%c=(((a*a)%c)*a%c)*a%c)....,这样算法的执行效率为O(b),当n很大时仍然无法进行处理。方案二:将b转换成一个二进制,即b=p(0)+p(1)*2^1+p(2)*2^2+...+p(n)*2^n,所以a^b=a^p(0) * a^(p(1)*2^1原创 2012-04-14 09:53:38 · 788 阅读 · 0 评论 -
博弈论小结
博弈论,今天算是告一段落了。首先来了解一下什么事博弈模型:①博弈模型为两个人轮流决定的非合作博弈,即两个人轮流进行决策,并且每次都会采用最优策略。②博弈模型必须是有限布可以完成的。③对两个人的规则是公平的。为了方便理解这个模型我们来定义两个状态:P状态(必败态):前一个选手(Previous player)将取胜的位置称为必败点。 N状态(必胜态):下一个选手(Next原创 2012-04-13 21:16:14 · 1011 阅读 · 0 评论 -
日期的处理
记住闰年的二月是29天,曾经在这里摔过/*需要注意的有①、②、③、④三点。*/#include int Month[]={0,31,59,90,120,151,181,212,243,273,304,334,365};//③struct Date{ int year; int month; int day; Date(int year,int month,int原创 2012-04-14 14:41:40 · 635 阅读 · 0 评论 -
Prim算法与Dijkstra算法的区别
在图论中,Prim算法是计算最小生成树的算法,而Dijkstra算法是计算最短路径的算法。二者看起来比较类似,因为假设全部顶点的集合是V,已经被挑选出来的点的集合是U,那么二者都是从集合V-U中不断的挑选权值最低的点加入U,那么二者是否等价呢?也就是说是否Dijkstra也可以计算出最小生成树而Prim也可以计算出从第一个顶点v0到其他点的最短路径呢?答案是否定的,否则就不必有两个算法了。二者转载 2011-12-14 20:10:47 · 555 阅读 · 0 评论 -
有向图强连通分量的Tarjan算法
程序会出现乱码,调成编辑状态可还原原文链接:http://www.byvoid.com/blog/scc-tarjan/[有向图强连通分量]在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。非强连通图有向图的极大强连通子图,称为强连通分量(strongly connect转载 2012-02-28 21:25:45 · 358 阅读 · 0 评论 -
最短路径算法---Bellman-Ford
1.Dijkstra算法:http://www.wutianqi.com/?p=18902.Floyd算法:http://www.wutianqi.com/?p=1903Dijkstra算法是处理单源最短路径的有效算法,但它局限于边的权值非负的情况,若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的。这时候,就需要使用其他的算法来求解最短路径,Bell转载 2012-02-07 22:09:01 · 866 阅读 · 0 评论 -
并查集学习
并查集学习:主要思想:对一个集合进行分类,分成多个相关联的集合。优化方法:路径压缩int p[nMax];void init(){ for(int i=0;i<nMax;p[i]=i,i++);}int find_set(int a){ return p[a]==a?a:p[a]=find_set(p[a]);//状态压缩:p[a]=find_set(p[原创 2012-02-06 21:43:36 · 418 阅读 · 0 评论 -
最短路径算法---SPFA
求最短路径的算法有许多种,除了排序外,恐怕是OI界中解决同一类问题算法最多的了。最熟悉的无疑是Dijkstra,接着是Bellman-Ford,它们都可以求出由一个源点向其他各点的最短路径;如果我们想要求出每一对顶点之间的最短路径的话,还可以用Floyd-Warshall。SPFA是这篇日志要写的一种算法,它的性能非常好,代码实现也并不复杂。特别是当图的规模大,用邻接矩阵存不下的时候,用S转载 2012-02-07 22:46:54 · 553 阅读 · 0 评论 -
集合上的动态规划---最优配对问题(推荐:*****)
/*提醒推荐:五星刘汝佳《算法竞赛入门经典》,集合上的动态规划---最优配对问题题意:空间里有n个点P0,P1,...,Pn-1,你的任务是把它们配成n/2对(n是偶数),使得每个点恰好在一个点对中。所有点对中两点的距离之和应尽量小。状态:d(i,S)表示把前i个点中,位于集合S中的元素两两配对的最小距离和状态转移方程为:d(i,S)=min{|PiPj|+d(i-1,S-{i}-原创 2012-05-01 21:54:01 · 5407 阅读 · 7 评论 -
动态规划---状态压缩(即集合上的动态规划)
参考博客:http://godfrey90.iteye.com/blog/725562一、首先谈谈什么是状态压缩?状态压缩就是将一个阶段或(集合)的状态使用二进制0、1进行表示,这类问题中,状态只存在两种:有或无。通过二进制来达到节省存储空间和查找效率的作用。二、什么是动态规划?动态规划是通过定义某一个状态,这个状态可以通过性质相同的另一个(或多个)状态推导出来,即存在最优原创 2012-05-02 16:04:59 · 2034 阅读 · 0 评论 -
字符串处理 --- 最小表示法
最小表示法:循环数组中,使用字典序最小的一个序列来表示这个数组。例如A[5] = {5, 1, 3, 2, 4},则最小表示法为{1, 3, 2, 4,5}。问题:输入两组数据,这两组数据都是循环数组或者环状数组,判断这两组数据是否一致?设两个数组分别为A[],B[]。解决方案:正常解题思路:使用两个for循环进行O(n * n)次判断即可KMP方法:将A复制一份加到A原创 2012-08-02 09:12:28 · 831 阅读 · 0 评论 -
网络流总结(二)
这些天学习网络流,总结了一下用到的主要算法,主要从下面几个方面来介绍一、常见的几种算法二、这些算法的复杂度三、这些算法适合处理的问题四、算法模板FF方法(Ford_Fulkerson):所有增广路径问题都是以Ford_Fulkerson方法为基础,之所以称为方法而不是算法,因为它提供的是一种思想。Ford_Fulkerson(s,t) f = 0,对自定义流f原创 2012-07-28 22:52:46 · 804 阅读 · 0 评论