
Algorithm
文章平均质量分 55
迷亭1213
帅帅帅
展开
-
2-SAT问题
2-SAT问题问题的提出有 N 个变量,每个变量只能有两种可能的取值。再给定 M 个条件,每个条件都是对这两个变量的取值限制。求是否存在对 N 个变量的合法赋值,使 M 个条件均得到满足。这个问题被称为 2-SAT (satisfiability)问题。一般形式设一个变量 Ai(1 <= i <= N)的取值可能是 0 或者 1,或者称 p 或 q。那么 2-SAT 问题中 M...原创 2020-01-04 18:12:42 · 1886 阅读 · 0 评论 -
莫比乌斯函数与莫比乌斯反演
以下笔记整理自:《算法设计编程实验》吴永辉1.结论1.1 莫比乌斯函数:莫比乌斯函数可以看做一个辅助函数,它在莫比乌斯反演公式中用到。1.2 莫比乌斯反演:莫比乌斯反演公式是 根据和函数来求算数函数的一个公式。1.3 算数函数:所有在正整数上运算的函数称为算数函数。1.4 和函数:设 f 是算数函数,f 的和函数为。其中d为n的约数,所以 f 的和函数F(n)就是n的所有约数的...原创 2019-01-27 14:20:41 · 836 阅读 · 0 评论 -
博弈论-SG函数笔记
例一:给定n堆物品,第 i 堆物品有 Ai 个。两名玩家轮流行动,每次可以任选一堆,取走任意多个物品,可把一堆取光,但不能不取。取走最后一件物品者获胜。两人都采用最优策略,问先手能否获胜。1.概念1.1 局面:游戏过程中面临的状态称为局面。1.2 先手与后手:整局游戏第一个行动的称为先手,第二个行动称为后手。1.3 最优策略:若在某一局面下存在某种行动,使得行动后对手面临必败局...原创 2018-12-16 12:31:34 · 550 阅读 · 0 评论 -
二分搜索算法笔记C++
1.背景1.1 结论在有序数组中查找某个值,或者在求最优解问题时,二分搜索非常有用。思想一般是先假定一个解,并判断是否可行,接着缩小解的范围继续判断。1.2 概念二分搜索法,是通过不断缩小解可能存在的范围,从而求得问题最优解的方法。在程序设计竞赛中,经常可以见到二分搜索法和其他算法结合的题目。2.二分搜索2.1思想二分答案转化为判定。一个宏观的最优化问题也可以抽象为函数...原创 2018-12-20 15:14:18 · 1161 阅读 · 2 评论 -
POJ2947解题报告
原题链接:POJ2947思路:本题是用高斯消元以及同余方程做,但是需要注意整数高斯消元避免使用除法。还需注意同余方程的解的问题、方程式与未知数个数不等问题。错误报告:这题总时间花了应该有七八个小时了。第一次做忽略了方程式个数不等于未知数个数时情况,并且对于何时无解、何时多解判断方法错误,在消元方面我使用了最小公倍数(异曲同工哈?)避免消元后出现的小数。今天又用了近四小时更改,发现如下错误:...原创 2018-11-27 18:18:42 · 8873 阅读 · 0 评论 -
矩阵快速幂模板C++
思路:和整数快速幂一样,唯一不同的就是存放结果的矩阵初始值为单位矩阵,通过重载运算符*后,代码可以大大简化。另外需要注意的是取模问题,我把模M放在了全局变量,这样省却一些麻烦,可以根据自身需要调整,这个无伤大雅。代码示例:#include<iostream> #include<cstdio> #include<cstring> using ...原创 2018-12-04 21:41:52 · 7517 阅读 · 0 评论 -
异或空间与高斯消元
1.异或空间相关概念1.1 异或空间:依据线性空间的概念,我们可以进一步推广,不限于向量、向量加法和标量乘法。“异或空间”也是一个很常见的形式。异或空间是一个关于异或运算封闭的非负整数集合。可以在异或空间中用类似方法定义“表出” “线性无关” “基底” 等概念。(注:线性空间又称向量空间,是线性代数中的重要概念,用来处理代数运算以及其它更抽象的问题。)1.2 表出:若整数b能由整数 a1,...原创 2018-11-29 12:00:07 · 9374 阅读 · 0 评论 -
Manacher算法笔记 C++
Manacher算法简介:1.作用:Manacher算法又名马拉车算法,用来求一个字符串中最长回文子串的长度。2.复杂度分析:时间复杂度为O(n)。算法核心思想:1.伪代码:假设str为待判断的字符串,len[ i ]数组存放以该 str[ i ] 字符为中心的最长回文子串的长度,mid为当前最长回文子串的中点,mx为当前最长回文子串的右边界,那么对当前位置 i 有如下伪代码:(此...原创 2018-11-16 19:03:55 · 10118 阅读 · 0 评论 -
矩阵乘法模板C/C++
由于矩阵相乘是诸多算法中的基础,就像乘法之于快速幂一样,所以有必要熟练掌握,以下模板是我个人觉得用起来比较方便的,但是随着时间迁移肯定是需要对其进行精进的。代码示例:struct Matrix{ int n,m; int v[maxn][maxn]; Matrix(int n,int m):n(n),m(m){} void init(){ //初始化矩阵 memse...原创 2018-11-12 12:34:34 · 14292 阅读 · 2 评论 -
Baby Step,Giant Step算法模板
介绍:BSGS(Baby Step,Giant Step)算法是用来求高次同余方程的解的算法。模板:P148//baby step giant step#include<iostream>#include<map>#include<cmath>using namespace std;typedef long long ll;ll q_pow...原创 2018-11-11 15:48:37 · 8889 阅读 · 0 评论 -
拓展欧几里得算法模板
代码示例:求出ax + by = c的所有解#include<cstdio>int exgcd(int a,int b,int& x,int& y){ if(b == 0){ x = 1,y = 0; return a; } int d = exgcd(b,a%b,x,y); int t = x; x = y,y = t - a/b*y; r...原创 2018-11-04 21:19:44 · 8760 阅读 · 0 评论 -
Miller_Rabin测试法
简介:Miller_Rabin法是一种简便的素数测试方法,一般用于测试大数是否为素数。Miller_Rabin测试原理:如果n是素数,且与a互质,则 。(1)证明:请参考费马小定理证明方法。思路:依据上述原理,我们可以不断选取与 n 互质的 a ,如果上式(1)都成立的话,那么n可能是一个素数,否则一定不是一个素数。如此一来只要a取得够多,就可以保证结果的准确度。一般在32位内的任一个...原创 2018-12-25 11:32:59 · 988 阅读 · 0 评论 -
子字符串查找之Rabin-Karp算法
1.背景1.1 算法简介:M.O.Rabin和R.A.Karp发明了一种基于散列的字符串查找算法。我们只需要计算模式串的散列函数,然后利用相同的散列函数计算文本中所有可能的M个字符的子字符串散列值并寻找匹配。如果找到了一个散列值和模式字符串相同的子字符串,再继续验证是否相同。这是一个有趣的算法,重点不在于其只用线性时间解决问题,而在于其对散列技术的使用,这是一个具有启发性的算法!1.2 结...原创 2019-01-01 19:13:22 · 1052 阅读 · 0 评论 -
拓展KMP算法
问题模型:给定字符串S和子串T,S的长度为n,T的长度为m;求字符串T与字符串S的每一个后缀d的最长公共前缀。拓展KMP算法假设 extend[] 数组: extend[i] 表示 T 与 S[i, n] 的最长公共前缀,目的是求出所有的 extend[0~n-1]。(注意到,如果存在extend[i] = m,则说明 T 在 S 中完全出现过,那么问题就变成标准KMP算法了。)我们下面...原创 2019-09-25 10:51:48 · 245 阅读 · 0 评论 -
HDU3085 Nightmare Ⅱ
HDU3085 Nightmare Ⅱ题意描述给定一张N* M的地图,地图中有1个男孩,1个女孩和2个鬼。字符“.”表示道路,字符“X”表示墙,字符“M”表示男孩的位置,字符“G”表示女孩的位置,字符“Z”表示鬼的位置。男孩每秒可以在道路上移动3个单位距离,女孩每秒可以在道路上移动1个单位距离。每个鬼占据的区域每秒可以向四周扩张2个单位距离,并且无视墙的阻挡,也就是在第k秒后所有与鬼的曼哈顿...原创 2019-07-18 08:56:09 · 361 阅读 · 0 评论 -
求2的n次方对1e9+7的模
有如下问题:求2^n mod (1e9+7),其中1< n < 10^100000。首先明确一下此类问题的几种算法,首先朴素算法,即暴力循环求解,是O(N)复杂度,适用范围应该是n小于1000000;然后是快速幂算法,效率是O(log N),适用于n小于2100000级别的;然后就是上面的例题了,由于范围是10100000,即使是快速幂也不可能在期望时间内解决,这时候需要另辟蹊...原创 2019-06-01 23:05:23 · 5141 阅读 · 1 评论 -
最短路径算法
前置知识: 图的相关定义、图的存储摘要:最短路径算法中常用的有4个:Floyed-Warshall、Dijkstra、Bellman-Ford、SPFA。这几种算法区别在于适用范围,以及对于不同构造的图效率不同。由于边的权值可以为负,在边权为负的情况下Dijkstra算法无法使用。而Bellman-Ford算法虽然可以处理负边权图,但却不能处理负权回路的情况(文中有介绍)。进一步的,我们可以...原创 2019-05-21 12:27:39 · 1262 阅读 · 0 评论 -
CDQ分治笔记
CDQ分治笔记1.结论CDQ分治可以用来解决偏序问题,尤其对于三维偏序问题适用。CDQ分治重要思想:计算一个子问题对另一个子问题的贡献。CDQ分治的优劣:写起来较为简单,对时空有很大的优化;缺点是必须离线操作。2.二维偏序问题2.1逆序对逆序对: 设 A 为一个有 n 个数字的有序集 (n>1),其中所有数字各不相同。如果存在正整数 i, j 使得 1 ≤ i <...原创 2019-04-02 20:35:16 · 301 阅读 · 0 评论 -
划分树笔记
划分树笔记问题模型:对于给定的n个元素的序列A,有m次询问,每次询问给L ,R,K,请求出位于[L,R]内第K大的数。解题思路:朴素算法:用快速排序。由于我们有m次询问,而每次询问区间左右端点是不同的,故如果对每个询问进行排序,我们在得到答案后还需要将序列恢复原状。按照快速排序的效率O(nlgn),m次询问就是O(mnlgn)。如果m和n都很大,效率就低的可怜。划分树:由于划分树...原创 2019-04-10 16:13:50 · 241 阅读 · 0 评论 -
前缀和、差分与树上差分
1.结论1.1 前缀和:前缀和可以通过对一个序列进行O(n)的预处理后,在O(1)时间内求出任意一个子序列的和。1.2 差分:可以用于求解多次区间修改与区间询问的题型,例如多次次给[ l , r ] 内所有数 + val,就可以用差分以及前缀和来优化。区间操作O(1),区间询问O(n)处理,O(1)查询。1.3 树上差分:同样的,如果我们有若干次操作与若干次询问,每次操作对从u 到 v...原创 2019-03-04 20:59:32 · 1597 阅读 · 0 评论 -
背包问题-笔记整理
本文为个人笔记,这算是我第三次系统的学背包问题。根据老师所写课件,所记为个人感悟以及知识点梳理,方便日后复习,如有不足之处请斧正,感谢。1.背景:1.1 什么是背包问题:背包问题指这样一类问题,题意往往可以抽象成:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。(来自百度百科)1.2 背包问题的种类:就ACM或者其它算法竞赛...原创 2019-02-24 16:18:10 · 63916 阅读 · 13 评论 -
(环上)最大子段和
1.背景最大连续子段和是一类问题,即求一个序列最大连续子序列的和。问:给出n个元素分别为A1,A2,...,An,求出其最大连续子段和。2.求解思路2.1 动态规划:设A[ i ]为该序列第 i 个元素,C[ i ]存放前 i 个序列的最大子段和,那么C[ i ]有两种可能结果:2.2 问题2:A1,A2,...,An 首尾相连,求出该环上最大子段和。2.3 问题2...原创 2019-02-01 17:37:36 · 1447 阅读 · 0 评论 -
欧拉函数与线性筛模板
代码实例:求单个欧拉函数。分解单个数,可以用循环来实现,不必借助辅助数组。线性筛求欧拉函数://求欧拉函数phi #include<cstdio>int phi(int n){ int ans = n; for(int i = 2;i*i <= n;i++){ if(n%i == 0) ans = ans/i*(i-1); while(n%i == 0)...原创 2018-10-30 15:53:47 · 8889 阅读 · 0 评论 -
求N所有正约数
题意:给定一个正整数N(N < 2*10e9),求N所有正约数。解题思路:10e9之内约数个数最多的数的约数个数为1536个。我们可以计算根号N的所有质数,进而求出其约数。代码实例://唯一分解定理//前10000个数中有1229个素数 //10e9自然数内,约数最多的数的约数个数为1536 //我们只能算到2*10e5 #include<iostream>...原创 2018-10-30 15:25:16 · 11320 阅读 · 0 评论 -
KMP算法--Next数组详解与优化
本篇文章直接跳过蛮力算法以及一些简单背景,着重讨论Next数组的意义以及其是如何工作的,并对如何求Next数组做详细记录。1.背景1.1 KMP算法的应用:KMP算法用来解决模式串匹配问题。1.2 为什么要用KMP算法:普通的蛮力算法时间复杂度为O(n*m),而KMP为O(n+m)。2.KMP算法思想2.1 KMP算法的思想:(称T为目标串,P为待查找字串)目标串T的 ...原创 2018-10-15 17:15:15 · 14133 阅读 · 2 评论 -
Dijkstra算法 C++
个人笔记,仅供复习,整理自陈越老师的网课1.适用范围:解决无负权边的带权有向图或无向图的单源最短路问题2.算法思想:贪心思想,每次从当前结点出发走下一个权值最小的边。3.伪代码:令S={源点s + 已经确定了最短路径的顶点vi}对任一未收录的顶点v,定义dist[v]为s到v的最短路径长度,但该路径仅经过S中的顶点。即路径{s->(vi属于S)->v}的最小长度若路径是按照递增(非递减...原创 2018-07-15 09:19:43 · 627 阅读 · 0 评论 -
C/C++ 子集生成算法整理
个人笔记,仅供复习1.概念:给定一个集合,枚举所有可能的子集。2.常用算法增量构造法位向量法二进制法3.增量构造法3.1 思路:一次选出一个元素放到集合中。3.2 代码实例:void print_subset(int n,int *A,int cur){ for(int i = 0;i < cur;i++) cout << A[i] << " ";//打印当前子集 ...原创 2018-07-03 13:56:25 · 8029 阅读 · 0 评论 -
C++ 求枚举排列的两种方法
枚举排列常用的方法有两种:一是递归枚举,二是用STL中的next_permutation。1.枚举递归:2.next_permutation: 头文件:#include<algorithm> 原型:bool next_permutation(iterator begin,iterator end);已排好序的数组每次调用在原数组进行下一次排列如果当前序列不存在下一个排列时,...原创 2018-07-02 22:56:33 · 17642 阅读 · 0 评论 -
基本模运算
1.概念:模运算是指取模运算,即求m/n的余数。模运算有许多基本规则,熟练掌握可以更好的编程。2.交换律: (a + b) % m = (b + a) % m (a * b) % m = (b * a) % m3.结合律: [(a+b)%m+c]%m = [a+...原创 2018-06-06 23:03:33 · 27714 阅读 · 0 评论 -
离散化方法
个人笔记,仅供复习1.概念:离散化就是把无限空间的有限个体映射到有限空间去,从而大幅节省空间或时间。基本思想就是在众多可能的情况中“只考虑我需要用的值”2.适用范围:除了对于较大整数需要使用离散化之外,对于一些需要使用整型数据结构,但给出的数据却是小数的也可以使用离散化,将其索引为整数就可以了。3.一般步奏:排序去重建立索引4.例题:Uva12171// UVa12171 Sculpture//...原创 2018-06-13 18:29:25 · 8574 阅读 · 0 评论 -
C++ 快速幂运算
1.概念:快速幂运算也叫反复平方法。顾名思义,算法就蕴含在名字中。2.原理: 假设要求x^n,如果n = 2^k,那么原题可以很轻松的表示为:x^n = ((x^2)^2)^2…。这样只要做k次平方运算就能解决,时间复杂度就从O(n)下降到log(n)。 由上面的分析可知,只要幂运算的幂可以写成2^k的形式,就可以用上面的方法降低时间复杂度。所以我们可以将任意的实数n改写有限个2^k的...原创 2018-06-05 20:21:14 · 38046 阅读 · 4 评论 -
C++尺取法
1.概念:所谓尺取法,顾名思义,就是像一把尺子(固定某一条件),不断向右(左)移动,不断更新所求答案。一般用来求满足条件的最小区间。2.实现步骤:初始化左右端点不断扩大右端点,直至满足条件如果直至终点也无法满足条件,则终止,否则更新结果扩大左端点(右移1),跳回步骤23.伪代码:4.例题:给定一个整数S,求一个长度为n的序列(所有元素均为正整数)中总和不小于S的连续子序列的长度的最小值,如果不存在...原创 2018-05-15 20:21:21 · 6923 阅读 · 0 评论 -
C++ 用随机数(rand)测试代码的方法
cstdlib中的rand()可生成闭区间[0,RAND_MAX]内均匀分布的随机整数,其中RAND_MAX至少为32767。如果要生成更大的随机整数,在精度要求的情况下可以用rand()结果“放大”得到。所谓的放大就是执行rand()之后先除以RAND_MAX,得到[0,1]之间的随机实数,扩大n倍之后四舍五入,得到[0,n]之间的均匀整数。#include<iostream>#i...原创 2018-05-09 15:47:53 · 6043 阅读 · 0 评论 -
C/C++高精度运算(大整数运算)详解(含压位)
1.高精度加法1.1 高精度加法高精度运算的基本运算就是加和减。和算数的加减规则一样,模拟竖式计算,考虑错位运算与进位处理。下面是我老师给的代码,目前比网上其他的代码要精简和巧妙。#include <cstdio>#include <cstring>int main(){ char a[202]={0}, b[202]={0...原创 2018-04-22 22:49:50 · 26287 阅读 · 13 评论 -
Bellman-Ford 与 SPFA 算法笔记
个人笔记,仅供复习1.Bellman-Ford算法1.1 适用范围:含负权边的带权有向图的单源最短路问题。不能处理带负权边的无向图1.2 限制条件:要求图中不能包含权值总和为负值回路(负权值回路),如下图所示:1.3 算法思想:1.3.1 构造dist[k][u]:算法构造了一个最短路径长度序列dist[k][u]。其中:dist[1][u]是从源点v到终点u的只经过一条边的最短路径长度,并有di...原创 2018-07-15 10:29:00 · 2580 阅读 · 2 评论 -
Floyd算法 笔记 C/C++
个人笔记,仅供复习1.适用范围:求每一对顶点之前的最短路径(适用稠密图)2.算法思想:在一般情况下,若(vi,…,vk )和( vk,…,vj )分别是从 vi 到 vk 和从 vk 到 vj 的 中间顶点的序号不大于k的最短路径,则将( vi,…, vk ,… , vj )和已经得到的从vi到vj且中间顶点的序号不大于k-1的最短路径相比较,其长度较短者便是从vi到vj的中间顶点的序号不大于k的...原创 2018-07-15 10:53:18 · 951 阅读 · 1 评论 -
递推式计算与矩阵乘法 C++
以斐波那契数列为例,计算斐波那契数列的矩阵方法代码如下:(快速幂、矩阵乘法)《挑战程序设计竞赛第二版》P199#include<iostream>#include<vector>using namespace std;typedef vector<int> vec;typedef vector<vec> mat;int M = 1...原创 2018-07-29 20:22:32 · 565 阅读 · 0 评论 -
kd-树笔记
以下内容均为本人近几天学习笔记,个人理解,并非完美答案,请抱着怀疑眼光阅读,如有错误请告知,感谢!1.kd-树简介1.1 特征:在任何情况下,kd-树都是一棵递归定义的平衡二叉搜索树1.2 用途:常用于范围查询,高效解决多维范围查询。例如:快速在校友数据库中找到1970-2000年毕业并且身高在170-190cm且性别为男的校友。2.kd-树的实现2.1 一维kd-树:一维...原创 2018-10-05 19:42:48 · 8915 阅读 · 0 评论 -
逆元inv详细整理
个人笔记,仅供复习1.概念1.1 定义:逆元素是指一个可以取消另一给定元素运算的元素,在数学里,逆元素广义化了加法中的加法逆元和乘法中的倒数。1.2 数论中定义:如果满足公式,a*b = 1(mod P),则a是b的逆元,同时b也是a的逆元。1.3 另一种定义:a*x = 1 (mod P),其中a与P互质,则称x的最小整数为a关于P的逆元。2.逆元的应用2.1 除法...原创 2018-09-23 21:36:21 · 11304 阅读 · 1 评论 -
AVL树的调整(笔记)
1.定义二叉树:二叉树是每个结点最多有两个子树的树结构。 二叉搜索树:二叉搜索树(Binary Search Tree),它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉搜索树。平衡二叉搜索树:平衡二叉搜索树(Self-balanc...原创 2018-09-06 20:22:19 · 9752 阅读 · 0 评论