数据结构算法
文章平均质量分 66
plussai
这个作者很懒,什么都没留下…
展开
-
经典DP--LIS
要去百度面试,心情很复杂,复习一下DPDP经典问题,LIS---最长上升子序列。设A[i]表示序列中的第i个数,F[i]表示从1到i这一段中以A[i]结尾的最长上升子序列的长度,初始时设F[i] = 0(i = 1, 2, ..., len(A))。则有动态规划方程:F[i] = max{1, F[j] + 1} (j = 1, 2, ..., i - 1, 且A[j] < A[i...原创 2011-05-04 21:14:56 · 91 阅读 · 0 评论 -
线段染色,矩形切割,离散化---zoj_2301,zoj_1128
染色问题:在一维坐标轴上(最右端为M),有N个(a,b,c)的染色操作,即把在坐标(a,b)之间的线段染成颜色c.最后来求解一系列问题。如:最长的颜色为C的区间,每种颜色的总长度,每种颜色的区间段数等等。 矩形切割问题:在二维坐标轴上,给出N个矩形,这N个矩形可能相互包含,交叉,分离。最后求解一系列问题。如N个矩形所覆盖的面积,相交的面积等。 ...原创 2011-06-24 22:32:21 · 143 阅读 · 0 评论 -
线段树---zoj_1610
线段树是一种二叉树的拓展,在线段树每个节点中,存储的是一个区间范围。对于每个节点,它的数据结构一般有,left,right,*lch,*rch,分别描述的是区间的左端点,区间的右端点,指向左子树的指针,指向右子树的指针。对于一个节点的左子树,它的区间范围是[left,(left+right)/2],对于一个节点的右子树,它的区间范围是[(left+right)/2,right]。...2011-06-22 21:06:04 · 168 阅读 · 0 评论 -
快速排序(qsort)
快速排序是一种高效的非稳定排序,它的基本思路是分支法,在一个序列a[]中找到一个数a[mid],然后将序列a[]分为3部分a[start]---a[i-1],a[i],a[i+1]---a[end],第一部分的序列中,所有的数都小于a[i],第二部分的序列中,所有的数都大于a[i]。然后递归的对前后两部分进行处理,直到序列完成排序。 那么快速排序的关键步骤就是对...2011-06-16 17:03:32 · 105 阅读 · 0 评论 -
斐波那契散列
斐波那契散列法其实是一种特殊的乘法散列,先来看乘法散列.根据算法导论第2版中的定义,构造乘法散列函数包含两个步骤。第一步,用关键字k乘上常数A(0<A<1),并抽取出kA的小数部分。然后,用m乘以这个值,再结果的低。总之,散列函数为h(k)=[m(kA mod 1)] 一般来说,m取值为2^p,而A的取值为形如s/2^w的分数(w为计算机的字长,int32,l...2011-06-16 16:38:39 · 3722 阅读 · 0 评论 -
NIM博弈游戏,SG函数---zoj_3084,zoj_2083
Nim游戏是两个人进行的游戏有如下规则: 1)桌子上有 N 堆石子,游戏者轮流取石子。 2)每次只能从一堆中取出任意数目的石子,但不能不取。 3)取走最后一个石子者胜。 为了求解这一类问题,我们通常要引出SG函数和游戏和的概念 SG函数:对于单一游戏的某一个状态u,sg(u)=mex(sg(v)|...原创 2011-09-23 23:00:10 · 147 阅读 · 0 评论 -
强连通分支(scc)---tarjan
本文大量参考:http://www.nocow.cn/index.php/%E5%BC%BA%E8%BF%9E%E9%80%9A%E5%88%86%E9%87%8F 感谢:byvoid 首先,强连通分支是定义在一个有向图G上的。一个有向图的强连通分支就是一个最大的顶点集合,在这个集合中,所有的点都是互为可达的,即对于每一个点对(u,v)都...原创 2011-06-15 16:17:41 · 450 阅读 · 0 评论 -
多重背包--zoj_2156
首先介绍经典的三种背包问题,0-1背包,完全背包,多重背包。0-1背包是背包问题的最简形式,其他的很多背包问题都可以转化为0-1背包来解决,而0-1背包问题也有非常简单的解法,时间效率为O(V*N),空间消耗为O(V),这里不要小看空间消耗,在数据量很大时,大量的取地址操作也会占用不少的时间消耗。 0-1背包问题可以这样描述:给出N个背包,每个背包的重量为c[i...原创 2011-09-14 11:10:27 · 112 阅读 · 0 评论 -
单源最短路径SPFA---zoj3146
针对Bellman-Ford算法效率比较低的问题,SPFA是用一个队列来进行维护。初始时将源加入队列。每次从队列中取出一个元素,并对所有与他相邻的点进行松弛,若某个相邻的点松弛成功,则将其入队。直到队列为空时算法结束。它可以在O(kE)的时间复杂度内求出源点到其他所有点的最短路径,有办法证明对于通常的情况,k在2左右。 值得注意的一点是,如果某个点进入队列...原创 2011-06-09 15:25:13 · 82 阅读 · 0 评论 -
笛卡尔树以及treap---zoj_2243
zoj_2243笛卡尔树的构造,开始被topcoder上的教程吸引去看这题。题目中说这种数据结构叫treap然后就按照treap的insert加上左旋右旋去做了,结果果断TLE。然后网上找了一下关于笛卡尔树的资料,发现了一些问题的端倪。 首先,treap和笛卡尔树从形式上来说是完全一样的,即是一颗二叉搜索树和二叉堆的结合(不是严格意义上的二叉堆,因为二叉堆是一颗完全...2011-07-07 15:52:40 · 303 阅读 · 0 评论 -
LAC的tarjan(离线)算法---zoj_1141
LCA就不解释了,这里主要再次复习一下LCA的tarjan的离线算法,所谓离线算法,就是把Q个查询先预存储起来,然后等预处理完成后,一次性处理Q个查询。相反所谓在线算法,即使输入一个查询就处理一个查询。今后会补上LCA的ST在线算法。 tarjan我非常崇拜,他解决了图论中很多问题,基本上都是基于DFS的,比如SCC,LCA等,那么tarjan离线如何运行呢,其中...2011-07-08 17:52:40 · 163 阅读 · 0 评论 -
图的割点tarjan---zoj_1119
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1119 如果将连通图G中的某个点及和这个点相关的边删除后,将使原图不再连通,那么这个点就称为图G的割点或是接合点。如果一个无向图没有割点,则这样的图被称为双连通图。 算法用到了一下两个数组。 dfn:这个点在dfs序列...原创 2011-10-24 23:00:45 · 169 阅读 · 0 评论 -
二分图最大匹配(匈牙利算法)--zoj1516,1525,2223
二分图G(E,V)将点集合V分成两个部分L,R,使得,图G中所有属于E的边相关联的两个点分别在L和R中。 二分图的一个匹配,即是图G中的边集合,其中,任意两条边都不共用一个顶点,或者说,每个顶点都之多只有一条边和它相关联。 二分图中的最大匹配M,就是求边数最大的边集合。 求二分图匹配有很多算法,这里介绍两种,效率都是O(EV)。...原创 2011-07-20 22:36:35 · 289 阅读 · 0 评论 -
网络最大流(EK)---zoj_1734
网络最大流是图论中的一个典型问题,为了精确的定义最大流问题,先给出下面几个定义。 一、流网络:G(E,V)是一个有向图,对于G中的每一对顶点(u,v)均有一非负的容量c(u,v),如果(u,v)属于E,那么c(u,v)>0,否则c(u,v)=0. 二、流:设G(E,V)是一个流网络,那么G的流是定义在V*V上的一个实值函数f,并且满足一下三个性...2011-07-19 16:34:34 · 254 阅读 · 0 评论 -
BFS与双向BFS---zoj_1505
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=505 题目大意,跳棋,8*8的棋盘,上有4个棋子,给你一个初始状态给你一个结束状态,问能不能在8步之内从初始状态走到结束状态。 一般的想法,直接暴力DFS,使用状态压缩,状态表偷懒使用set,用时2S 如果使用...原创 2011-10-09 17:14:01 · 274 阅读 · 0 评论 -
trie和前缀检查---zoj_2876
trie树是一种多叉树,广泛用于字典检索。如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树。额,有点晚了,具体不写了。看代码吧。。zoj_2876#include<iostream>#include<cstdio>#include<string>using namespace std;bool res=fal...原创 2011-07-13 23:03:27 · 185 阅读 · 0 评论 -
位图bitmap
bitmap是一种广泛使用的数据结构,主要用在数据压缩,索引等方面,它最小单位为位,即01结构。通常情况下逻辑状态为是非二值状态时,bitmap比较常用。 如:腾讯面试题:给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中? 显然可以发现,需要判断给出的整数是否存在,是一个二值逻...原创 2011-07-13 21:08:02 · 119 阅读 · 0 评论 -
LAC和RMQ的转化---zoj_3195
我擦。。纠结了好久啊,从SF到TLE,先总结2个错误1:(int)(log(1.0*(b-a+1))/log(2.0));注意括号。2:i+(1<<(j-1))位移操作符加上括号,以后一定要记住,不然就是(1+i)<<j-1,这我去。解决掉越界,然后使用c输入输出,使用++i,最后终于AC了 这题其实LCA的tarjan也可以搞,但是tar...2011-07-12 22:35:50 · 162 阅读 · 0 评论 -
静态treap+线段树---zoj_2112
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2112 终于A了这惊天地泣鬼神的一题,练习了线段树和treap。。。此题要求对于N个正整数,给定M个操作,操作有两种1)输入 i j k,要求输出a[i]到a[j]中第k大的数.2)i q,将a[i]修改为q. 这题的特点是数...原创 2011-09-29 23:06:57 · 166 阅读 · 0 评论 -
单源最短路径Bellman-Ford---zoj3033
Bellman-Ford算法的特点是能够解决带负权值的最短路径问题,并且实现起来比较简单。整个循环体循环V-1次,每次循环遍历图中的每一条边(u,v),并对点V做松弛操作。可以证明,通过V*E次的操作,最后得到的dist[i]值就是从原点到点i的最短路径。具体的Bellman-Ford的正确性证明见《算法导论》 但是,Bellman-Ford算法有一种情况不能...原创 2011-06-09 15:20:10 · 110 阅读 · 0 评论 -
最小生成树之kruskal(并查集)---zoj_1586
今天细读了算法导论的21章不相交集合,也就是传说中的并查集,有点小收获。原来网上搜的并查集只介绍了路径压缩,今天第一次听说还有按秩合并这回事儿。算法导论上说,同时利用按秩合并和路径压缩技术处理,并查集的操作速度可以大大提升。设有一连串的make-set,find-set,union操作共m个,其中make-set有n个,在渐进意义上,这一连串的操作的时间复杂度为O(m*a(n)),...原创 2011-06-07 22:33:40 · 219 阅读 · 0 评论 -
八数码问题(A*&&双向BFS)---zoj_1217
题目地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=217 首先说一下八数码问题的可解性。 1.互换2个非零位置,状态的逆序奇偶性将保持不变。 2.互换0和另一个非零位置,状态的逆序奇偶性将发生颠倒。 3.因此,如果目标状态和起始状态的逆序奇偶性相同,问题可解,...原创 2011-08-30 22:13:56 · 222 阅读 · 0 评论 -
非递归组合算法
order数组是栈指针,利用栈指针将递归问题转化为回溯的非递归问题[code="c++"]#include#includeusing namespace std;int getCombine(int*a,int* order,int m,int n){while(1){ int flag=0; for(int i=1;i...2010-10-28 17:14:06 · 146 阅读 · 0 评论 -
递归组合算法
递归组合算法算法思想:对于一个长度为M的序列,要求N个数的组合。1.从索引最小的元素遍历到第N-M个元素,将遍历到的元素定为组合中的第一个元素2.判断组合中N个元素是否已满,如果满了,打印该组合,如果不满重,则截取1中选择的元素之后的序列,复步骤一。[code="c++"]#include#includeusing namespace std;void getCom...原创 2010-10-26 22:59:05 · 282 阅读 · 0 评论 -
并查集---zoj_2833
并查集被评为历史上最经典的算法。其形式很简单,但是可以对数据进行很高效的处理。并查集的主要功能为1)合并两个不相交的几何2)查找元素是否在同一个集合中。 并查集为简单的树形结构,没一个节点指向它的父节点,根节点指向它自己。我们可以用一个数组father[]来表示元素的父子关系,用一个数组count[]来表示每一个节点所在集合的元素个数。 并查集可以提供几个操作1)获...2011-05-22 22:30:58 · 124 阅读 · 0 评论 -
单源最短路径----Dijkstra
dijkstra算法个人感觉挺怪异的,不过复杂度O(n2),速度快,但是不能理解WSM很多人都推荐用FLOYD,可能是实现简单吧,但是FLOYD必须用邻接矩阵来实现。两者的功能上稍有不同,dijkstra算法对于输入的节点,能够找出该点到所有其他点的最短路径。 基本的算法思路是,把图中的点集分为2部分,一部分为访问过的点(即已经找到了输入点到该点的最短路径),另一部分为还没访问到...2011-05-12 19:54:58 · 95 阅读 · 0 评论 -
单源最短路径----FLOYD
FLOYD用于求图中任意点对的最短路径,DP,时间复杂O(N3),状态转移方程dist[i][j]=min{dist[i][j],dist[i][k]+dist[k][j]},dist[i][j]表示节点i到节点j的最短路径,如果dist[i][j]的值发生改变,path[i][j]=k,表示从节点i到节点j需要连续经过i,k.如path[0][5]=4,path[4][5]=3,path[3...2011-05-12 19:33:53 · 179 阅读 · 0 评论 -
痛定思痛!!我的LCA
从哪里跌倒从哪里爬起来,明年我会再来见你的,亲爱的百度HR。艰苦的路从LCA开始。如何求一棵树中节点的最近公共先祖,Tarjan算法,复杂度O(N)网上说O(N+E)有点不太能理解,基于深度优先搜索和并查集。 算法基本思路,从根开始深度遍历,经过任意一个节点,都要以该节点为根建立一个集合,随着深度遍历的进行,当一个节点的子节点标记被访问时(即该子节点的所有子节点都标记被访问),...2011-05-12 00:52:27 · 70 阅读 · 0 评论 -
经典DP--LCS
先在百度上抄两段: 问题:已知序列X,Y,求序列Z,使得Z是X,Y的子序列,不要求连续,且Z严格递增 最长公共子序列是一个十分实用的问题,它可以描述两段文字之间的“相似度”,即它们的雷同程度,从而能够用来辨别抄袭。对一段文字进行修改之后,计算改动前后文字的最长公共子序列,将除此子序列外的部分提取出来,这种方法判断修改的部分,往往十分准确。简而言之,百度知道、百度百科都用得上。 ...原创 2011-05-04 21:37:42 · 60 阅读 · 0 评论 -
模式串匹配---KMP
朴素的的模式串匹配算法通常要在向前移动文本指针之后,回溯模式串指针,其效率为O(m*n),而KMP算法则挖掘了一些模式串中的一些信息,来加快匹配的效率。 KMP算法的紧随便是覆盖函数next。当模式串p[j]和文本串s[i]失配时,j指针不是简单的回溯,而是指向next[j]。 覆盖函数next如何定义呢,它本质上是找到即是模式串p的前缀,又是它...原创 2011-08-31 20:49:54 · 81 阅读 · 0 评论 -
hashTable
问题:要处理200000个自然数,统计每个不同的自然数出现的次数(不同的自然数个数小于10000)。 算法思路:将N个不同的键值对nodePair(num,value)存在一张HashTable中,可以达到O(1)的存取效率(不考虑冲突) 1)使用什么样的HASH函数,这里使用fibonacci散列法。 HashCode=n*265435769>>...2011-05-24 20:05:26 · 65 阅读 · 0 评论 -
关于最小生成树
安全边:在无向图G=(V,E)中,A是图G的某棵最小生成树T的子集,当把图G中的某条(u, v)边加入到A中后,如果AU(u, v)仍然是某棵最小生成树T’的的子集,边(u, v)被成为A的一条安全边割:在无向图G=(V,E)中,割(S, V-S)是对顶点集V的一种划分,当一条边(u, v)的一个端点属于S,另一个端点属于V-S时,称边(u, v)通过割(S, V-S)。如果集合A中没...原创 2011-06-07 17:13:22 · 119 阅读 · 0 评论 -
模线性方程----zoj_2305
推论1:方程ax=b(mod n)对于未知量x有解,当且仅当gcd(a,n) | b。 推论2:方程ax=b(mod n)或者对模n有d个不同的解,其中d=gcd(a,n),或者无解。 定理1:设d=gcd(a,n),假定对整数x和y满足d=ax+by(比如用扩展Euclid算法求出的一组解)。如果d | b,则方程ax=b(modn)有一个解x0满足x0=x*(b/d) mo...原创 2011-06-04 21:32:39 · 147 阅读 · 0 评论 -
筛法打素数表---zoj_1951
筛法打素数表是一种高效的打表方法,体做法是:先把N个自然数按次序排列起来。1不是质数,也不是合数,要划去。第二个数2是质数留下来,而把2后面所有能被2整除的数都划去。2后面第一个没划去的数是3,把3留下,再把3后面所有能被3整除的数都划去。3后面第一个没划去的数是5,把5留下,再把5后面所有能被5整除的数都划去。c这样一直做下去,就会把不超过N的全部合数都筛掉,留下的就是不超过...2011-06-04 21:18:58 · 138 阅读 · 0 评论 -
分解质因数----zoj_1133
循环从2开始,到sqrt(a),每次判断a是否能被i整除,如果可以,则将i存如vector中,a/=i,然后--i,目的是继续判断i,因为a可能可以被i整除多次.到循环结束的时候,再将a存入vector中。#include<iostream>#include<vector>#include<cmath>using namespac...原创 2011-06-03 14:30:42 · 241 阅读 · 0 评论 -
最小生成树之prim---zoj_1586
在一个具有几个顶点的连通图G中,如果存在子图G'包含G中所有顶点和一部分边,且不形成回路,则称G'为图G的生成树,代价最小生成树则称为最小生成树。 许多应用问题都是一个求无向连通图的最小生成树问题。例如:要在n个城市铺设光缆,主要目标是要使这 n 个城市的任意两个之间都可以通信,但铺设光缆的费用很高,且各个城市之间铺设光缆的费用不同;另一个目标是要使铺设光缆的总费用最低。这就...2011-06-01 22:37:10 · 96 阅读 · 0 评论 -
优先队列---二叉堆
使用二叉堆来实现优先队列,可以应用与图的最短路径,最小生成树等算法。优先队列包含一下功能,buildHeap_MIN,效率为O(N), extract_MIN,效率为O(logN), decrease_key,效率为O(logN)等。#include<iostream>#include<string.h>#include<fstream&g...2011-06-01 22:29:48 · 78 阅读 · 0 评论 -
zoj_3123二分与分治
分治思想求解,超时了分析了一下T(n)=O(n)+O(logn)*k(k可能渐进为n)#include<iostream>#include<stdio.h>using namespace std;int cases,total,sum;const int maxm=100000;int array[maxm];int enumFind(int*a...原创 2011-05-25 23:08:22 · 139 阅读 · 0 评论 -
huffman编码---zoj_1117
huffman编码是一种优化的编码方法,于ASCII等固定长度的编码方法相比较,他可以使编码的长度缩短。其主要的思路是,让出现频率高的字符拥有较短的编码,让出现频率较低的字符,拥有较长的编码。但是,这样的编码方式就要求任意一个字符的编码不能是其他字符编码的前缀,通常这种编码方式叫前缀编码。 huffman编码通过构造huffmanTree来实现,贪心思想。取权值(频率)最低的2个...2011-05-25 16:20:53 · 389 阅读 · 0 评论 -
ac自动机以及它上面的DFA
AC自动机(Aho-Corasick)主要用于多模式串的匹配问题,是前缀匹配搜索的一种方法,和KMP算法的思想类似。 总所周至,KMP算法中的关键next指针利用了模式串本身的性质,在失配时给出了重新匹配的位置。AC自动机中的fail指针也是一样,fail指针的构造关键是找到即是当点匹配串的后缀,又是trie中一个模式串的前缀的最长的字符串。 ...原创 2011-08-08 23:04:17 · 1067 阅读 · 0 评论