◆学习笔记
nyist_xiaod
这个作者很懒,什么都没留下…
展开
-
二分查找
/* 形如:for(int i=0;i<n;i++) if(f(i) >= c) //其中,f 为 i 的函数,c 为与 f 无关的量,大小于符号可以任意. break; 都可以写成二分的形式,将O(N)的复杂度降为O(logN).*/int Binary_Search(int *a,int l,int r,翻译 2012-07-21 15:05:18 · 4469 阅读 · 0 评论 -
Tarjan算法求SCC(有向图强连通分量)
http://www.byvoid.com/blog/scc-tarjan/zh-hans/http://blog.csdn.net/shiqi_614/article/details/7833628dfn[u] 表示在 dfs 中 u 被访问的顺序标号。(时间戳 / time stamp)low[u] 表示 u 在栈中可以追溯到的的最远祖先的 dfn。若 u 的子节点 v翻译 2012-08-06 10:24:19 · 3120 阅读 · 0 评论 -
Tarjan算法求LCA(最近公共祖先)
LCA的离线算法。复杂度为O(n+q)。这个算法充分利用了dfs树的结构。对于每个节点u,关于它的询问(u,v)只有两种。(假设先dfs(u)后dfs(v))1、v在u的子树内。此时LCA(u,v) = u.2、v不在u的子树内。⑴假设v在u的父亲的另一棵子树内。此时LCA(u,v) = father[u].⑵如果不满足条件⑴,则v可能在u的父亲的父亲的另一棵子树内翻译 2012-08-03 19:57:49 · 3582 阅读 · 0 评论 -
线段树学习(一)
先从书上把定义抄下来:一棵二叉树,记为 T (a,b),参数 a,b表示该节点表示区间[a,b)。区间的长度b-a 记为 L。递归定义 T[a,b]: 若 L>1 :[a, (a+b)/2]为 T 的左儿子,[(a+b) /2,b]为 T 的右儿子。 若 L=1 :T 为一个叶子节点。区间[1, 10]的线段树表示方法如下: 这里需要注意一点,图中一共有9个叶子节点,也原创 2012-03-29 16:26:29 · 1817 阅读 · 2 评论 -
扩展欧几里得算法
如果事先不了解 欧几里得算法 ,请点击。扩展欧几里得算法:对于不完全为0的非负整数 a,b,必然存在整数对 X,Y,使得 aX + bY = gcd(a,b)。解法见注释。/* How to solve "aX + bY = gcd(a,b)" ?1、if b=0, gcd(a,b) = a, X = 1 , Y is any number.翻译 2012-09-13 09:43:03 · 747 阅读 · 0 评论 -
高斯消元(解线性方程组 or 线性同余方程组)
解线性方程组或线性同余方程组。陪队友写了 1 天,挺爽的。目前还没有考虑 无关变元 的情况。#include #include #include #include using namespace std;typedef long long LL;int gcd(int a,int b){ return b ? gcd(b,a%b) : a;}int lcm(翻译 2013-07-16 03:48:37 · 1582 阅读 · 0 评论 -
后缀数组(SA倍增算法)
我就不吐槽我看了几天了。论文里写的代码,真是呵呵。#include #include #include using namespace std;const int N = 5e4 + 3;int sa[N],rank[N],rank2[N],height[N],cnt[N],*x,*y;/* * a radix_sort which is based on the y翻译 2013-08-05 17:36:54 · 2146 阅读 · 0 评论 -
图的邻接表实现
以前邻接表都用vector,今天学习了下一种手写的邻接表,学会后也挺方便的。传上来和大家分享~~。#include #include #define CLR(arr,val) memset(arr,val,sizeof(arr))#define Max_n 100005#define Max_e 10005struct Vertex{ int head;翻译 2012-05-11 14:10:37 · 3954 阅读 · 0 评论 -
三分查找
我们都知道 二分查找 适用于单调函数中逼近求解某点的值。如果遇到凸性或凹形函数时,可以用三分查找求那个凸点或凹点。下面的方法应该是三分查找的一个变形。如图所示,已知左右端点L、R,要求找到白点的位置。思路:通过不断缩小 [L,R] 的范围,无限逼近白点。做法:先取 [L,R] 的中点 mid,再取 [mid,R] 的中点 mmid,通过比较 f(mid) 与 f(mmi翻译 2012-08-31 11:24:15 · 1868 阅读 · 0 评论 -
矩形 面积并 && 周长并
算是线段树的一个应用吧,在 hanyan 学长的帮助下,一天搞定了,略爽。问题是,平面上有 n 个矩形,矩形的边是平行于 x 轴或 y 轴的,问它们覆盖的面积和周长。大概思路是,用一根垂直于 x 轴的直线,从左向右扫描。扫描的过程中,一定会与某些矩形的边重合。由于 n 个矩形会有 2*n 条竖边,所以我们可以把它们分成 2*n-1 个缝隙,我们依次考虑这些缝隙的情况,最后相加即翻译 2013-04-16 19:48:50 · 2209 阅读 · 0 评论 -
最小生成树
Prim。#include #include #define CLR(a,v) memset(a,v,sizeof(a))#define min(a,b) a < b ? a : b#define N 105#define M 10005struct Vertex{ int head;}V[N];struct Edge{ int v,w,next;}E[M翻译 2012-07-24 08:34:54 · 715 阅读 · 0 评论 -
AC自动机
#include #include #include #include using namespace std;#define CLR(a,v) memset(a,v,sizeof(a))namespace Trie{ const int N = 1e6 + 5; const int Size = 26; int top; struct Node翻译 2013-09-07 12:52:23 · 768 阅读 · 0 评论 -
网络流
EK求最大流。复杂度O(n*m*m)。#include #include #include using namespace std;#define N 205#define M 405#define INF 0x7fffffff#define min(a,b) a < b ? a : b#define CLR(a,v) memset(a,v,sizeof(a))st翻译 2012-07-29 16:11:08 · 813 阅读 · 0 评论 -
欧拉函数
欧拉函数 phi(n) = 1~n中,gcd(i,n)=翻译 2014-04-27 16:41:27 · 1968 阅读 · 0 评论 -
指针+内存池的优化
#include #include #include using namespace std;struct T { int x; T(){} T(int _x):x(_x){} bool operator < (const T& B) const { return x < B.x; }};templatestruct Cm翻译 2014-05-16 13:25:12 · 2206 阅读 · 0 评论 -
康托展开与逆康托展开
int fac[]={1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800};int cantor(char* s){ int n = strlen(s), ans = 1; for(int i=0;i<=11;i++) { int cnt = 0; for(int j=i+1;j<翻译 2014-03-23 16:39:09 · 2111 阅读 · 0 评论 -
快速排序
#include #include #include using namespace std;const int N = 1e6 + 5;int a[N];void quick_sort(int l,int r){ if(l >= r) return ; int magic = rand() % (r - l) + l + 1; swap(a[l],a[magic]翻译 2014-03-21 09:51:00 · 796 阅读 · 0 评论 -
Treap 的实现
学会 BST 后,Treap 就比较好学了。在 BST 的基础上,给每个节点加个随机的优先值,然后类似 Heap 的维护,让树中每个父节点的优先值大于子节点的优先值。这样随机以后,树高的期望高度被证明为 log(n)。从而使得操作的复杂度为 log(n) 。/* Title : Treap Author: nyist_xiaod Date : 2013翻译 2013-03-17 21:05:23 · 919 阅读 · 0 评论 -
判断有向图中是否有环
struct T{ int v,next;}E[N*N];struct TT{ int head;}V[N];bool used[N];bool dfs(int u){ if(used[u]) return true; used[u] = true; for(int i=V[u].head;i!=NULL;i=E[i].翻译 2012-07-23 19:02:56 · 1272 阅读 · 0 评论 -
匈牙利算法(二分图最大匹配)
匈牙利算法。复杂度为O(mn)。对每个点都找以它为起点的增广路,当找到增广路后,匹配数必定加1。#include #include const int N = 105;const int M = 10005;struct Vertex{ int head;}V[N];struct Edge{ int v,next;}E[M];int top,翻译 2012-08-02 18:01:18 · 820 阅读 · 0 评论 -
选择不相交区间(贪心)
数轴上有n个区间[ai,bi],要求选择尽量多个区间,使得这些区间两两没有公共点。贪心策略:按照b1证明:我们对a1,a2……的关系分以下几种情况考虑:1、a1>a2。 此时区间2包含区间1。这种情况下显然不会选择区间2,因为选择区间1会留下更多的剩余空间。 不仅区间2如此,以后所有区间中只要有一个 i 满足a1 > ai,i原创 2012-05-04 13:43:38 · 5027 阅读 · 0 评论 -
KMP算法
无聊,贴个KMP的代码,备忘。若想详细了解,点击 http://www.matrix67.com/blog/archives/115/#include #define MaxL 1000005int next[MaxL];int start,end;void Get_next(char *P){ next[0] = -1; for(int i=1,j=-1;P翻译 2012-06-07 20:21:55 · 1695 阅读 · 0 评论 -
Tarjan算法求BCC(无向图连通块、割边、割点)
http://www.byvoid.com/zhs/blog/biconnecthttp://blog.csdn.net/shiqi_614/article/details/7833628#include #include #include #include using namespace std;const int N = 2e3+5;const int翻译 2013-04-10 09:45:50 · 3369 阅读 · 0 评论 -
堆(Heap)的实现
学习了 Heap,其实不难。用途:在 O(log(n)) 的时间内插入、返回和删除最大值或最小值。它是这样一颗二叉树,父节点的值总是大于(小于)子节点的值(为了方便,我们把这句称作“要求”)。显然,Heap 的树根就是那个动态的最大值或最小值。首先需要一个维护堆的性质的函数 heapify,它的作用是,当以节点 i 为根的堆不满足要求时,调用这个函数使其满足要求。翻译 2013-03-14 21:38:50 · 1038 阅读 · 0 评论 -
斐波那契博弈(Fibonacci Nim)
有一堆个数为n(n>=2)的石子,游戏双方轮流取石子,规则如下:1)先手不能在第一次把所有的石子取完,至少取1颗;2)之后每次可以取的石子数至少为1,至多为对手刚取的石子数的2倍。约定取走最后一个石子的人为赢家,求必败态。结论:当n为Fibonacci数的时候,必败。f[i]:1,2,3,5,8,13,21,34,55,89……用第二原创 2012-05-25 18:48:41 · 26477 阅读 · 10 评论 -
大数
还没有学JAVA,留作纪念,目前只支持大数相加,相乘,求幂,比较大小。#define CLR(a,v) memset(a,v,sizeof(a))const int base = 1000;struct BigNum{ int d[55],len; BigNum(int l=0){CLR(d,0);len=l;} BigNum(char* num,int l=翻译 2012-12-20 20:18:17 · 764 阅读 · 0 评论 -
求两条直线(线段)的交点
如图,如何求得直线 AB 与直线 CD 的交点P?以上内容摘自《算法艺术与信息学竞赛》。思路就是利用叉积求得点P分线段DC的比,然后利用高中学习的定比分点坐标公式求得分点P的坐标。看不懂的可以去复习下 定比分点 的知识。#include #include #include #include using namespace std;#define翻译 2012-09-06 22:31:03 · 35341 阅读 · 6 评论 -
最短路
Dijkstra。#include #include #define CLR(a,v) memset(a,v,sizeof(a))#define min(a,b) a < b ? a : b#define N 105#define M 10005struct Vertex{ int head;}V[N];struct Edge{ int v,w,next;翻译 2012-07-24 09:01:24 · 641 阅读 · 0 评论 -
求凸包
Graham's Scan法 求解凸包问题。我写的是按照逆时针扫描,其中叉乘函数返回的是的结果。凸包的结果保存在栈S[0...top]中。PS:1、求凸包时,必须确定至少有3个点。2、一般把极点 S[0] 在最后 S[top+1] 处复制一份,便于计算。3、初始化放2个点即可,3个点可能有bug(考虑开始三个点即 P[0]、P[1]、P[2] 共线的情况)。翻译 2012-08-31 16:56:44 · 2219 阅读 · 1 评论 -
并查集
弄了n年,终于弄出了个并查集的模板。贴上备忘。简易版。#include #include #define CLR(a,v) memset(a,v,sizeof(a))#define N 50010int pre[N];void Init(){ CLR(pre,-1);}int Root(int x){ return pre[x]+1 ? pre[x] =翻译 2012-07-08 08:25:43 · 524 阅读 · 0 评论 -
区间选点问题(贪心)
数轴上有n个闭区间[ai,bi]。取尽量少的点,使得每个区间内都至少有一个点(不同区间内含的点可以是同一个)。贪心策略:按照b1证明:为了方便起见,如果区间i内已经有一个点被取到,我们称区间i被满足。1、首先考虑区间包含的情况,当小区间被满足时大区间一定被满足。所以我们应当优先选取小区间中的点,从而使大区间不用考虑。 按照上面的方式排序后,如果出现区间包含的情况,原创 2012-05-04 14:27:24 · 10298 阅读 · 2 评论 -
字典树(Trie)
好像静态的比动态的好,无聊,写了个静态的。#include #include #define CLR(a,v) memset(a,v,sizeof(a))#define MAX 1000010struct Trie{ bool in; Trie* next[26]; //可变}Node[MAX];int top;inline Trie翻译 2012-06-11 10:06:35 · 1766 阅读 · 2 评论 -
区间覆盖问题(贪心)
数轴上有n个区间[ai,bi],选择尽量少的区间覆盖一条指定线段[s,t]。贪心策略:把各区间按照a从小到大排序,从前向后遍历,然后每次选择从当前起点S开始的最长区间,并以这个区间的右端点为新的起点,继续选择,直到找不到区间覆盖当前起点S或者S已经到达线段末端。需要注意的是,如果某一区间边界大于s,t的边界,应把它们变成s或t。因为超出的部分毫无意义,同时还会影响对数据的分析。经典原创 2012-05-04 20:13:45 · 9773 阅读 · 0 评论 -
RMQ问题之Sparse_Table算法
RMQ问题,全名(Range Minimum/Maximum Query),是求给定区间中的最值问题。主要方法及复杂度如下:1、朴素(即搜索),O(n)-O(qn) online。2、线段树,O(n)-O(qlogn) online。3、Sparse_Table(实质是动态规划),O(nlogn)-O(1) online。4、RMQ标准算法:先规约成LCA(Lowest C翻译 2012-03-24 11:17:04 · 2155 阅读 · 2 评论 -
威佐夫博弈(Wythoff Game)
有两堆各若干个物品,两个人轮流从某一堆或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜。这种规则下游戏是颇为复杂的。我们用(a[k],b[k])(a[k] ≤ b[k] ,k=0,1,2,...,n)表示两堆物品的数量并称其为局势。如果甲面对(0,0),那么甲已经输了,这种局势我们称为奇异局势。首先列举人们已经发现的前几个奇异局势:(0,0)、原创 2012-03-27 14:39:49 · 1919 阅读 · 0 评论 -
生成函数(母函数)
生成函数,英文是Generating Function。恕本人不才,本文只介绍生成函数的其中一种用法。生成函数是说,构造这么一个多项式函数g(x),使得x的n次方系数为f(n)。对于母函数,我看到最多的是这样两句话:1.“把组合问题的加法法则和幂级数的乘幂对应起来。”2.“把离散数列和幂级数一 一对应起来,把离散数列间的相互结合关系对应成为幂级数间的运算关系,最后由幂级数形式来确定原创 2012-03-23 10:24:56 · 5581 阅读 · 6 评论 -
KM算法(二分图最大权匹配)
http://blog.163.com/huangbingliang@yeah/blog/static/94161399201011291044527/复杂度O(n^3)。#include #include #include using namespace std;const int N = 305;const int Inf = 1e9;int top,mat翻译 2013-03-22 13:26:39 · 809 阅读 · 0 评论 -
2-SAT
论文题目链接:Click here~~复杂度O(E)。#include #include #include #include #include #include using namespace std;const int N = 16005;const int M = 40005;struct Vertex{ int head;}V[N],VV翻译 2013-04-05 19:33:48 · 778 阅读 · 0 评论 -
矩阵
无聊写了个矩阵的模板,传上备用。Matrix preSum(Matrix A,int k){ if(k == 1) return A; Matrix sum = preSum(A,k/2); if(k&1) { Matrix Ak_1 = A.pow(k/2+1); return sum + Ak_1 +翻译 2012-09-21 10:40:58 · 659 阅读 · 0 评论 -
二叉排序树(BinarySortTree)的实现
/* Title : Binary Sort Tree Author: nyist_xiaod Date : 2013.3.16*/#include #include #include using namespace std;#define BSTdef#define Pnn pair#ifdef BSTdef#define Pre(root,par翻译 2013-03-16 20:57:05 · 981 阅读 · 0 评论