模板
哈希表扁豆
此人不懒,但什么都没写
展开
-
【模板】自适应辛普森积分
模板:自适应辛普森积分原创 2022-06-29 11:05:57 · 163 阅读 · 0 评论 -
【模板】最小割树(Gomory-Hu Tree)
ProblemSolution做模板使用,不证明(不会证 。原图中两点间的最小割为最小割树上两点间最小割,可通过树上倍增询问。最小割树的建立:任意两点间的最小割将当前点集分成两部分,以此为基础分治,每次从当前点集中任取两点求最小割,将最小割作为Gomory-Hu Tree上两点间的边权,并根据最小割将当前点集分成两部分,s那边的与t那边的,边界就是当前点集中只有一个点。相当于跑了n-1次dinic。Code#include<iostream>#include<cstd原创 2022-05-16 23:05:49 · 247 阅读 · 0 评论 -
严格次小生成树
ProblemSolution做法与求非严格次小生成树类似(枚举非mst上的边来替换mst上的边)。需要同时维护最大边和严格次大边的倍增数组,不存在严格次大边的情况下需设为-inf,保证此次计算不会作为最终答案。关于严格次大边倍增数组的递推:取左右区间严格次大边的max,同时若左右区间的最大边不相等,两区间最大边的最小值。关于求树上两点间的严格次大边:假设待加入边权值为w,每次更新时若区间最大边<w,则用区间最大边更新,否则用区间的严格次大边更新。Code#include<i原创 2022-01-29 02:12:59 · 418 阅读 · 0 评论 -
非严格次小生成树
允许与mst权值和相等。#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<vector>using namespace std;const int maxn=150,maxm=100005;const int inf = 1e9;int t,n,m,cnt,mst,logg[maxn],mx[maxn][15],pre[.原创 2022-01-29 00:55:48 · 402 阅读 · 0 评论 -
朱刘算法板子
O(n3)图不断在构造,判自环不能省。无定根时设虚根,虚根向所有点连0。#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int maxn =70,maxm = 200005;const int inf = 1e9;int n,m,t,C,in[maxn],cnt,pre[maxn],id[max.原创 2022-01-18 01:16:16 · 101 阅读 · 0 评论 -
KM算法及应用整理
Kuhn-Munkers算法思想设立左右顶标l,规定l(u)+l(v)>=w(u,v),相等子图是包含满足l(u)+l(v)=w(u,v)所有边的生成子图,相等子图的完美匹配是原图的最大权完美匹配。通过调整顶标,贪心地将边权最大的边变成相等边,逐渐扩大相等子图。算法流程初始化顶标。(一般将左顶标设为最大边权)用匈牙利算法寻找可行匹配。若未找到则修改顶标。重复以上过程直至相等子图完备。最大权完美匹配模板通过状态延续使时间复杂度降至n3。vx,vy为单次标记的左右部的点,px,原创 2021-12-28 16:55:55 · 731 阅读 · 0 评论 -
【模板】无向图三元环计数
Problem给定一个 n 个点 m 条边的简单无向图,求其三元环个数。n<=1e5,m<=2e5。Solution枚举三个点O(n3),枚举临边O(m2),枚举点及其对边O(nm)都会T,根本原因在于任何一个简单三元环都会被枚举多次。于是我们可以得到一个直观的优化思路:避免对环的重复枚举。如果是有向图,对于一类子图的计数是不会出现重复统计,因此可以可以按照一个统一的规则将无向图转换成有向图?方法:对于一条边的两个端点,度小的连向度大的,度数相同的情况下编号小的连向编号大的,这原创 2021-09-18 17:49:24 · 345 阅读 · 0 评论 -
欧拉道路 (模板)
Problem求有向图字典序最小的欧拉道路,没有输出“No”P7771 【模板】欧拉路径Solution欧拉道路:一笔画,特别地,起点与终点相同时称为欧拉回路。有向图欧拉道路:一般情况:只存在一个出度比入度大一的点作为起点,只存在一个入读比出度大一的点作为终点,其余点入度与出度相等。特殊情况:欧拉回路,所有点的入度与出度相等。其余情况均不存在欧拉道路。求字典序最小的欧拉道路:对所有点所能到达的点按照字典序排序,然后dfs,注意,直接按照dfs序输出是不对的,因为一般情况下要保证终点最后到达原创 2021-09-18 16:44:24 · 507 阅读 · 0 评论 -
存个后缀数组板子
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn=2e4+5int n,k,a[maxn],m,wa[maxn],wb[maxn],wv[maxn],ws[maxn];int rank[maxn],height[maxn];int cmp(int *r,int a,int b,i原创 2021-08-10 16:34:48 · 73 阅读 · 0 评论 -
F - Icebergs(求简单多边形面积模板)
求多个简单多边形的面积和。以原点为基准点,求一圈向量的叉积,注意绝对值。#include<bits/stdc++.h>using namespace std;int n,t;long long x[1005],y[1005];double ans=0,sum;int main(){ cin>>t; while(t--) { sum=0; scanf("%d",&n); for(int .原创 2021-08-01 17:16:38 · 117 阅读 · 0 评论 -
Trie(前缀树)
字面意思,保存字符串前缀的树型结构。根到任意节点的路径代表一个前缀,每个结点一个编号,根的编号为0。Trie如上图,用二维数组ch[][]建树(类似邻接矩阵),ch[u][c]表示结点u通过编号为c的字母所到达的结点(u编号为c的子节点),同时为方便维护每个结点u对应权值val[u],如可以用来区分单词几点与非单词结点。UVA1401 Remember the Word Trie+Dp#include <iostream>#include <cstdio>#inc.原创 2021-06-15 21:36:27 · 138 阅读 · 2 评论 -
洛谷模板-高斯消元
换行、向前步骤、向后步骤。#include<stdio.h>#include<string.h>#include<math.h>double mx[105][105];int n,m,f;void div(int x){ double y=mx[x][x]; for(int i=1;i<=n+1;i++) mx[x][i]/=y;}void swapp(int x,int y){ int tmp; for(int i=1;i<.原创 2021-04-11 17:31:23 · 125 阅读 · 0 评论 -
线性推逆元
#include<iostream>#include<cstdio>using namespace std;long long inq[3000010];int main(){ int n,p; cin>>n>>p; inq[1]=1; cout<<'1'<<endl; for(int i=2;i<=n;i++) { inq[i]=(p-p/i)*inq[p原创 2020-11-03 20:05:33 · 73 阅读 · 0 评论 -
树上倍增求LCA
#include<iostream>#include<cstdio>#include<algorithm>using namespace std;int cnt,n,m,s,last[500005],f[500005][22],dep[500005],logg[500005];struct edge{ int next,v,u;}e[1000010];inline void inserts(int u,int v){ cnt++;原创 2020-11-03 20:26:59 · 90 阅读 · 0 评论 -
Tarjan割点
// 默认low[u]等于dfn[u]dfn[u] = low[u] = ++count;vis[u] = true;// 遍历与u相邻的所有顶点for (int v: g[u]){ // (u, v)为树边 if (!vis[v]) { // 递增子树数量 children++; // 设置v的父亲为u parent[v] = u; // 继续DFS dfs(v);原创 2020-11-03 20:08:29 · 71 阅读 · 0 评论 -
欧拉筛法
欧拉筛法的基本思想 :在埃氏筛法的基础上,让每个合数只被它的最小质因子筛选一次,以达到不重复的目的对于一个合数的分解:在欧拉筛法中将其分解成它的最小质因子与一个其它数的存乘积;欧拉筛法如果i是质数,那么就将它与之前的质数(包括它本身)的乘积筛掉 。如果i是合数,那么就将它与从2到它最小的质因子之间的质数的乘积分别筛掉。简单证明基于前面的分解方法,不会有合数被漏掉;假设i是合数,当j为i最小质因子的时候就break掉,不对i继续往后筛; 假设c=ij,i=kj,那么c=ki i,如果这.原创 2020-12-24 11:34:35 · 4334 阅读 · 1 评论 -
快读
inline int read(){ int s=0,w=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w;}原创 2020-12-15 11:19:17 · 101 阅读 · 0 评论 -
dinic模板
dinic在思想上是对原图分层得到层次图,然后找到当前层次图下的得到极大流(阻塞流),不断重复这个过程直到不再有增广路为止;将以前写的模板优化修改后的版本,增加了当前弧优化;看过紫书上的版本后感觉那个写法性能应该更好,当前弧优化的作用更高,但实际跑下来(洛谷模板)还是之前的那个一次bfs对多次dfs的版本跑的快一些,因此这里暂时保留之前版本;#include<iostream>#include<queue>#include<cstring>#include.原创 2020-12-01 20:09:47 · 203 阅读 · 0 评论 -
无向图的点·双联通分量
对于一个连通图G,如果任意两点间至少存在两条“点不重复”路径,则说这个图是点·双联通的。这个要求等价于图的内部无割顶。任意两点都在一个简单环中。对于一张无向图,点·双联通图的极大子图(类似强连通分量)称为双联通分量(BCC)或块(block)。不同双联通分量至多有一个公共点,这个公共点是割顶。计算双联通分量用Tarjan提出的如下算法,用一个栈来维护当前block中的边(其精髓与tarjan算法类似)。int bccno[maxn],iscut[maxn],dfn[maxn],low[maxn],.原创 2020-11-19 12:31:22 · 315 阅读 · 1 评论 -
求无向图中的割顶与桥
对于无向图G(方便起见只考虑联通图),如果删除某个点u后,连通分量数目增加,称u为图的关节点或割顶,对于连通图,割顶就是删除之后使图不再联通的点。对于连通图,删除一条边(u,v)后使图不在联通,则称(u,v)是桥。定理: 在无向图G的dfs树中,非根结点u是G的割顶当且仅当u存在一个子节点v使得v及其后代都没有连回u祖先(u不算)的边。可以类推出, 在无向图G的dfs树中,(u,v)是桥当且仅当v及其v的的后代除了无向边(u,v)以外不存在连回u及其u祖先的边。实现,与tarjan类似,dfn[i].原创 2020-11-18 19:35:30 · 141 阅读 · 0 评论 -
Tarjan缩点(复习整理)
若两顶点间至少存在一条路径,则称两个顶点强连通。若有向图G中每两个顶点都强连通,则称G为强连通图。非强连通图中的极大强连通子图称为强连通分量。Tarjan算法本质上是一种dfs。dfn[i]:dfs时被遍历的次序(时间戳)。low[i]:最早能回溯到的栈中的点的时间戳。stack[i]:判断i点是否在栈中。dindex:时间戳,stop:栈顶。强连通分量中的点在栈中必定是连续一段。如果一个点x无法回溯到在它之前且在栈中的点,假设它的头顶上还有点,这些点的low值为x或者连接点(连接的连接….原创 2020-11-10 20:26:04 · 415 阅读 · 1 评论 -
ST表(静态区间最大值)
#include<iostream>#include<cstdio>#include<cmath>using namespace std;int f[205010][20],n,m,lg[2000000],a[2000100],ans;inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}原创 2020-11-03 22:52:37 · 225 阅读 · 0 评论 -
spfa负环
// luogu-judger-enable-o2#include<iostream>#include<cstdio>#include<cstring>#include<queue>using namespace std;struct edge{ int v,w,next;}e[6010];int t,n,m,x,y,z,cnt,fang[2005],last[2005],d[2005],inq[2005],answer;inline原创 2020-11-03 22:51:21 · 56 阅读 · 0 评论 -
可持久化线段树(主席树)
#include<iostream>#include<cstdio>#include<algorithm>using namespace std;int n,m,root[200005],a[200005],len,b[200005],tot,li,ri,ki,ans;struct segmenttree{ int lc,rc; int cnt;}tree[4000005];int build(int l,int r){ int p=++tot;原创 2020-11-03 20:13:37 · 80 阅读 · 0 评论 -
线段树
#include<iostream>using namespace std;long long a[100002],tree[400009],ans,tag[400009];void pushup(int x){ tree[x]=tree[x<<1]+tree[x<<1|1];}void build(int x,int l,int r){ if(l==r){ tree[x]=a[l]; return; } int mid=(l+r)>.原创 2020-11-03 20:18:03 · 88 阅读 · 0 评论 -
文艺平衡树
#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;const int maxn=300009;int ch[maxn][2],fa[maxn],m,rev[maxn]={0},n,a[maxn],rt,size[maxn];void up(int x){ size[x]=size[ch[x][0]]+size[ch[x.原创 2020-11-03 20:23:30 · 97 阅读 · 0 评论 -
树状数组
#include<iostream>using namespace std;int a[500001],b[500001],xx[500001],y[500001],c[500001],m,n,k[500001],kk[500001];int lowbit(int x){ return x&-x;}void adds(int x){ int i=x; while(i<=n) { b[i]+=a[x]; i原创 2020-11-03 20:28:35 · 66 阅读 · 0 评论 -
二维凸包
#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>using namespace std;int n,top;double len;struct point{ double x,y; point operator - (point&s){ return (point){x-s.x,y-s.y}; }}a[10005];int p[10005原创 2020-11-03 20:30:33 · 73 阅读 · 0 评论 -
多源最短路算法——Floyd
Floyd是多源最短路算法,可得图中任意两点间的最短路。本质上是枚举中间点,属于动态规划。时间复杂度为O(n^3),用邻接矩阵实现。for(int k=1;k<=n;k++)//k为枚举的中间点 for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)d[i][j]=(d[i][j]>d[i][k]+d[k][j])?d[i][k]+d[k][j]:d[i][j]; ...原创 2020-08-06 15:29:54 · 374 阅读 · 0 评论 -
单源最短路算法——Dijkstra
Dijkstra算法是单源最短路算法,可以求解不带负权边的图中,从源点s到其它所有点的最短路。时间复杂度近似O(n^2),可以用堆优化。一般用邻接表,也可用邻接矩阵。在稠密图上会有较好的性能表现。在这里插入代码片...原创 2020-08-06 14:29:44 · 220 阅读 · 0 评论 -
单源最短路算法——SPFA
SPFA适用于稀疏图或者有负权边的图。由于其算法特性,使用邻接矩阵性能会大打折扣。时间复杂度一般认为是O(kE),E为边数,多数情况k=2。struct edge{ int v,w,next;}e[maxm];int last[maxn],d[maxn],cnt,s,t,inq[maxn];//inq用来表示某个结点是否在队列中(1/0),防止一个点被多次松弛后在队列中出现多次。 void spfa(){ queue<int>q;//q用来存点 for(int i=1;i.原创 2020-08-05 22:41:42 · 154 阅读 · 0 评论 -
邻接表模板
int cnt,last[maxn];//cnt:当前最后一条边的编号 last[u]:以u为起点,按照时间顺序所插入的最后一条边的编号 struct edge{//边表 int to,next,v;//v:权值 to:连向的边 next:同起点上一条边的编号 }e[maxn];void insert(int u,int v,int w){//插入起点为u,终点为v,权值为w的边 cnt++; e[cnt].to=v; e[cnt].v=w; e[cnt].next=last[u]原创 2020-08-05 12:14:51 · 122 阅读 · 0 评论 -
邻接矩阵
邻接矩阵int graph[maxn][maxn];void addedge(int u,int v,int w){//u到v建立权值为w的边 if(graph[u][v]>w) graph[u][v]=w;}memset(graph,0*3f,sizeof(graph));//初始距离为正无穷for(int i=1;i<=maxn;i++)//自身距离为0 graph[i][i]=0;for(int i=1;i<=maxn;i++)//遍历点x的出边 if(grap原创 2020-08-02 15:00:02 · 178 阅读 · 0 评论 -
关于刷表法
for(长度)for(左界)通过左界和长度定位右界;每次可以看成拿一段区间在数轴上平移,每一轮平移可以更新出这一区间长度+1的答案,然后下一轮拿区间长度+1的区间继续扫。原创 2020-10-15 23:25:38 · 473 阅读 · 0 评论 -
exgcd
//求解一组a*x+b*y=c 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 tmp=x; x=y; y=tmp-a/b*y; return d;}//判断是否有解 bool answer(int a,int b,int原创 2020-11-03 19:53:24 · 99 阅读 · 0 评论