算法和数据结构
算法和数据结构的总结
HZ35572
(ง •_•)ง
展开
-
线段树维护区间众数
线段树维护区间众数,需要维护三个值,分别是:以左端点为起点的最大连续长度ls,以右端点为终点的最大连续长度rs,区间的最大连续长度ms;需要注意以下细节:1.那么父区间的ls可以由左区间的ls向上合并得到,父区间的rs可以由右区间的rs向上合并得到。当然需要考虑左右区间为满区间的情况,如果相邻两个值相等且左右区间各自为满的情况需要考虑父区间的ls 和 rs跨到另一个区间的问题。父区间的ms可以由左区间的ms,右区间的ms,左区间的rs + 右区间的ls三者最大得到。2.查询的时候先查出左区间最大,再查出原创 2022-04-19 16:16:17 · 944 阅读 · 1 评论 -
带权并查集
代码#include<iostream>#include<algorithm>#include<cstdio>#define ll long longusing namespace std;const int N=1e5+10;const double esp=1e-5;const ll mod=1e9+7;int n,m,par[N],val[N];void init(){ for(int i=1;i<=n;i++){原创 2022-04-12 21:13:24 · 322 阅读 · 1 评论 -
博弈论(巴什博弈,威佐夫博弈,尼姆博弈)
文章目录一.巴什博弈二.威佐夫博弈三.尼姆博弈一.巴什博弈一堆n个物品,两个人从中轮流取出1~m个,最后取关者胜.同余定理:n=K*(m+1)+r;先取者拿走r个,那么后者无论拿走(1~m)个先者只要拿的数目和为m+1那么先者必赢.反之若n=K*(m+1)+r,那么先者必输.bool check(){ if(n%(m+1)) return true; else return false;}二.威佐夫博弈有两堆若干个物品,两个人轮流从任意一堆中取出至少一个或者同时从两堆中取出同样多的物品,原创 2022-03-03 15:32:26 · 679 阅读 · 0 评论 -
数论常用结论
结论:如果 a,b 均是正整数且互质,那么由 ax+by,x≥0,y≥0 不能凑出的最大整数是 ab−a−b。如果a,b不互质,那么一定不存在ax+by,x≥0,y≥0 不能凑出的最大整数数例题:AcWing 525. 小凯的疑惑代码:#include<iostream>#include<cstdio>#include<cstring>using namespace std;typedef long long ll;typedef pair<原创 2022-03-02 12:19:47 · 313 阅读 · 0 评论 -
IDA*算法
IDA*算法是迭代加深的A*算法,设计一个估价函数f(state)<=真实步数原创 2022-02-17 23:36:58 · 1401 阅读 · 0 评论 -
tarjan算法
文章目录tarjan算法介绍一、tarjan算法求强连通分量二、tarjan缩点三、tarjan求割点、桥tarjan算法介绍一、tarjan算法求强连通分量二、tarjan缩点三、tarjan求割点、桥原创 2022-02-11 00:16:50 · 558 阅读 · 0 评论 -
倍增法求LCA
文章目录一、倍增思想二、倍增求LCA一、倍增思想倍增, 从字面的上意思看就是成倍的增长 ,这是指我们在进行递推时,如果状态空间很大,通常的线性递推无法满足时间和空间复杂度的要求 ,那么我们就可以通过成倍的增长,只递推状态空间中在 2 的整数次幂位置上的值作为代表 。当需要其他位置上的值时,我们只需要通过" 任意整数可以表示成若干个2 的 次幂项的和 " 这一性质(13 = 23 + 22 +20 ), 使用之前求出的代表值拼成所需的值。关于倍增的理解可通过此博客:【白话系列】倍增算法二、倍增求LC原创 2022-01-30 20:02:37 · 359 阅读 · 0 评论 -
树状数组模板
文章目录一、树状数组介绍一、树状数组介绍原创 2022-01-23 13:07:28 · 1670 阅读 · 0 评论 -
字典树trie
文章目录trie树的作用原理基本操作和代码trie树的作用(1)串的快速检索给出N个单词组成的熟词表,以及一篇全用小写英文书写的文章,请你按最早出现的顺序写出所有不在熟词表中的生词。在这道题中,我们可以用数组枚举,用哈希,用字典树,先把熟词建一棵树,然后读入文章进行比较,这种方法效率是比较高的。(2)“串”排序给定N个互不相同的仅由一个单词构成的英文名,让你将他们按字典序从小到大输出用字典树进行排序,采用数组的方式创建字典树,这棵树的每个结点的所有儿子很显然地按照其字母大小排序。对这棵树进行先原创 2022-01-17 00:55:46 · 372 阅读 · 0 评论 -
线段树及其懒标记
懒标记基本原则:1、如果当前区间被完全覆盖在目标区间里,讲这个区间的sum+k*(tree[i].r-tree[i].l+1)2、如果没有完全覆盖,则先下传懒标记3、如果这个区间的左儿子和目标区间有交集,那么搜索左儿子4、如果这个区间的右儿子和目标区间有交集,那么搜索右儿子代码示例://洛谷P3372#include<iostream>#include<queue>#include<string>using namespace std;typede原创 2021-12-24 16:42:10 · 764 阅读 · 0 评论 -
哈夫曼算法
哈夫曼算法哈夫曼算法的一般步骤如下:1.初始化:由给定的 个权值构造nnn棵只有一个根节点的二叉树,得到一个二叉树集合FFF 。2.选取与合并:从二叉树集合FFF中选取根节点权值 最小的两棵 二叉树分别作为左右子树构造一棵新的二叉树,这棵新二叉树的根节点的权值为其左、右子树根结点的权值和。3.删除与加入:从FFF中删除作为左、右子树的两棵二叉树,并将新建立的二叉树加入到FFF中。4.重复 2、3 步,当集合中只剩下一棵二叉树时,这棵二叉树就是霍夫曼树。代码#include<stdio.原创 2021-12-22 20:26:27 · 2648 阅读 · 0 评论 -
二叉树的基本操作
//二叉树的创建和基本操作#include<stdio.h>#include<stdlib.h>#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0#define OVERFLOW -1typedef int Status;typedef char TElemType;typedef struct BitNode{ TElemType data;原创 2021-12-20 09:11:16 · 86 阅读 · 0 评论 -
A*算法解决八数码问题
A*算法核心A*算法是启发式算法的一种,其核心部分在于估值函数的设计:f(n)=g(n)+h(n),其中f(n)是每个试探点的估值,h(n)为当前节点到目标节点地估值.算法主要流程如下:首先将起始点s放入open表,将close表置空.(1).如果OPEN表不为空,从表头取一个结点n,如果为空算法失败。(2).判断n结点是否是目标点,如果是终止算法,否则继续搜索(3).将n的所有后继结点展开,就是从n可以直接关联的结点(子结点),如果不在CLOSE表中,就将它们放入OPEN表,并把s放入CLOSE原创 2021-12-16 15:10:52 · 9927 阅读 · 3 评论 -
实数二分(模板及例题)
POJ1905-Expanding Rods #include<iostream>#include<algorithm>#include<queue>#include<set>//#include<unordered_map>#include<stack>#include<cstdio>#include<vector>#include<cstring>#include<str原创 2021-12-13 10:12:25 · 151 阅读 · 0 评论 -
bellmanford算法模板
bellmanford算法:常用于判负环,进行了n轮松弛则说明有负环,可以利用这个性质判断差分约束系统是否有解#include<bits/stdc++.h>using namespace std;#define N 100010struct edge { int v, w;};vector<edge> e[N];int dis[N],n,m;bool bellmanford(int s) { memset(dis, 0x3f, sizeof(dis));原创 2021-11-28 21:27:19 · 758 阅读 · 0 评论 -
用顺序线性表实现归并排序
思路:分治思想,将线性表不断对半拆分,拆到只剩一个元素时就进行从小到大归并,递归实现代码:#include<stdio.h>#include<stdlib.h>#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define OVERFLOW -1#define LIST_INIT_SIZE 200 //线性表存储空间的初始分配量 #define LIST原创 2021-11-18 12:53:25 · 799 阅读 · 0 评论 -
二分图的染色与判定
Ps: 染色法可以用于判断一个图是否是二分图,也可以用于把一个二分图分成两部分原理:首先任意取出一个顶点进行染色,和该节点相邻的点有三种情况:1.如果未染色,那么继续染色此节点(染为另一种颜色)2.如果已染色但和当前节点颜色不同,则跳过该点3.如果已染色并且和当前节点颜色相同,返回失败(该图不是二分图)如果已知是二分图只染色不判断://col数组为染色后节点的颜色,初始为0void color(int x,int c){ col[x]=c; for(auto v:G[x]){原创 2021-08-27 11:30:41 · 186 阅读 · 0 评论 -
DAG拓扑排序
定义对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。Hint:若存在一条边i–>j,即从顶点i到顶点j的路径,则在拓扑序列中顶点i一定排在顶点j前面。操原创 2021-07-30 15:17:23 · 1161 阅读 · 0 评论 -
最短路--Dijkstra算法+堆优化
Dijkstra算法介绍(1)算法原理:从源点开始,更新每个与源点相连的点的最短距离d[i].然后每次以d[i]最小的顶点为中心,继续更新与该顶点相连的顶点的d[i],此时该点的最短距离已确定,后面不再关心该顶点.如上图,顶点1为源点,把d[1]设为0,先从点1开始,更新d[2]为2,d[3]为5,除去 d[1],由于d[2]最小,因此顶点2最短距离已确定,然后从顶点2开始更新d[i]大于d[2]的顶点的最短距离,依次类推.代码实现1.非优化版本#include<iostream>原创 2021-06-23 13:16:55 · 280 阅读 · 0 评论 -
并查集+最小生成树(Kruskal算法)
并查集并查集常用于解决一些元素分组问题,管理一系列不相交的集合,主要操作如下:初始化将所有节点的祖先初始化为其本身://初始化祖先节点,par[i]为i点的父节点,n为节点数量void init(){ for(int i=1;i<=n;i++){ par[i]=i; } return ;}查询查找祖先节点并且状态压缩,减小复杂度:int seek(int i){ if(par[i]==i)//若i点的父节点为它本身时,则i点为祖先节点原创 2021-06-02 14:12:21 · 831 阅读 · 0 评论 -
图的邻接表存储
原理邻接表是以边为单位存储图的方式,可用链表实现,一般用模拟数组实现以下是一张有向图的存储过程原创 2021-05-23 18:56:49 · 282 阅读 · 0 评论 -
最短路--SPFA算法
SPFA算法是 Bellman-Ford算法的队列优化版本,网上有很多用l邻接表原创 2021-05-19 18:27:14 · 153 阅读 · 0 评论 -
快速幂
快速幂算法主要是指快速幂取模算法。主要是依赖这连两个公式:abmodc=(amodc)bmodca^bmodc=(amod c)^b modcabmodc=(amodc)bmodc和a*b mod c=(a mod c * b mod c)mod c。推导过程我就不讲了,百度上查的到。1.如果b为偶数,例如b=8,则a8modca^8modca8modc的计算公式可以是这样:((a2modc)2modc)2modc((a^2modc)^2modc)^2modc((a2modc)2modc)2modc2.原创 2021-04-28 12:48:49 · 102 阅读 · 0 评论 -
欧拉筛法筛除n以内的合数
原理任何一个合数n都可以是n的最小质因数乘以另一个整数时间复杂度:O(n)代码#include<bits/stdc++.h>#define MAXN 1000005using namespace std;int prim[MAXN],i,n=MAXN,cnt=0,t;bool isp[MAXN]={false};int main(){ for(i=2;i<=n;i++){ if(!isp[i] prim[++cnt]=i;//把每个素数存起来 for(int原创 2021-04-10 22:44:11 · 279 阅读 · 3 评论