
数据结构和算法
重生之我会拧瓶盖
上岸
展开
-
Tire树模板
//trie树适用于快速存储和查询字符串数组#include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N = 1e5+10;int son[N][26],idx,cnt[N];char s[N];void insert(char *mh){ int p=0; for (int i=0;mh[i];i++) { .原创 2021-09-16 20:57:18 · 169 阅读 · 2 评论 -
区间修改乘和加(理解懒标记的好例题)
#include <iostream>#include <cstring>#include <algorithm>using namespace std;typedef long long LL;const int N = 1e5+10;int n,m,p;int a[N];struct Node{ int l,r; int sum,add,mul;}tr[N*4];void pushup(int u){ tr[u].su.原创 2021-08-20 11:43:36 · 141 阅读 · 0 评论 -
数位DP例题
空#include <iostream>#include <cstring>#include <algorithm>#include <vector>using namespace std;int get(vector<int> num,int l,int r){ int res = 0; for (int i=l;i>=r;i--) res = res*10 +num[i]; return res;.原创 2021-08-12 11:35:40 · 135 阅读 · 0 评论 -
状态压缩DP例题(旅行商问题和填矩形问题)
方便以后复习看一下给定一张 n 个点的带权无向图,点从 0∼n−1 标号,求起点 0 到终点 n−1 的最短 Hamilton 路径。Hamilton 路径的定义是从 0 到 n−1 不重不漏地经过每个点恰好一次。输入格式第一行输入整数 n。接下来 n 行每行 n 个整数,其中第 i 行第 j 个整数表示点 i 到 j 的距离(记为 a[i,j])。对于任意的 x,y,z,数据保证 a[x,x]=0,a[x,y]=a[y,x] 并且 a[x,y]+a[y,z]≥a[x,z]。输出格式输出一个原创 2021-08-11 16:32:11 · 211 阅读 · 0 评论 -
ST表学习
ST表的应用是解决RMQ问题,预处理建ST表的时间复杂度是O(log n),一般是解决求区间极值也可维护gcd的问题,高级应用是求区间里一个数字出现最多的次数,求次数。基本原理可以看这篇文章++++++++++++++++++++++++++++++++++ST表预处理#include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N = 5e4+1原创 2021-08-09 11:36:04 · 186 阅读 · 1 评论 -
乘法逆元作用
先说一下什么叫做逆元:逆元数论倒数,又称逆元数论中的倒数是有特别的意义滴你以为a的倒数在数论中还是1/a吗(・∀・)哼哼~天真先来引入求余概念(a + b) % p = (a%p + b%p) %p (对)(a - b) % p = (a%p - b%p) %p (对)(a * b) % p = (a%p * b%p) %p (对)(a / b) % p = (a%p / b%p) %p (错)为什么除法错的证明是对的难,证明错的只要举一个反例(100/50)%20 = 2 ≠ (转载 2021-08-06 17:52:09 · 142 阅读 · 0 评论 -
求组合数四种方法
给定 n 组询问,每组询问给定两个整数 a,b,请你输出 Cabmod(109+7) 的值。O(n*n)做法递推式预处理#include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N = 2010,mod = 1e9+7;int c[N][N];void init(){ for (int i=0;i<N;i++)原创 2021-08-06 17:46:41 · 370 阅读 · 0 评论 -
容斥原理(能被整除的数)
能被整除的数给定一个整数 n 和 m 个不同的质数 p1,p2,…,pm。请你求出 1∼n 中能被 p1,p2,…,pm 中的至少一个数整除的整数有多少个。输入格式第一行包含整数 n 和 m。第二行包含 m 个质数。输出格式输出一个整数,表示满足条件的整数的个数。数据范围1≤m≤16,1≤n,pi≤109输入样例:10 22 3输出样例:7#include <iostream>#include <cstring>#include <algo.原创 2021-08-06 11:21:22 · 249 阅读 · 0 评论 -
Nim游戏阶梯 Nim游戏和SG函数应用(集合游戏)
阶梯Nim 游戏现在,有一个 n 级台阶的楼梯,每级台阶上都有若干个石子,其中第 i 级台阶上有 ai 个石子(i≥1)。两位玩家轮流操作,每次操作可以从任意一级台阶上拿若干个石子放到下一级台阶中(不能不拿)。已经拿到地面上的石子不能再拿,最后无法进行操作的人视为失败。问如果两人都采用最优策略,先手是否必胜。输入格式第一行包含整数 n。第二行包含 n 个整数,其中第 i 个整数表示第 i 级台阶上的石子数 ai。输出格式如果先手方必胜,则输出 Yes。否则,输出 No。数据范围1≤n转载 2021-08-06 10:56:34 · 346 阅读 · 0 评论 -
高斯消元求n元方程组
#include <iostream>#include <algorithm>#include <cmath>using namespace std;const int N = 110;const double eps = 1e-6;int n;double a[N][N];int gauss(){ int c, r; for (c = 0, r = 0; c < n; c ++ ) { int t原创 2021-08-02 17:55:04 · 134 阅读 · 0 评论 -
扩展欧几里得算法和求同余方程
#include <iostream>#include <algorithm>using namespace std;int exgcd(int a, int b, int &x, int &y){ if (!b) { x = 1, y = 0; return a; } int d = exgcd(b, a % b, y, x); y -= a / b * x; return原创 2021-08-01 19:02:26 · 138 阅读 · 0 评论 -
欧拉函数和线性筛求欧拉函数
#include <iostream>#include <cstring>#include <algorithm>using namespace std;int phi(int x){ int res = x; for (int i=2;i<=x/i;i++) { if (x%i==0) { res = res/i*(i-1); while (x%i=.原创 2021-08-01 18:44:28 · 140 阅读 · 0 评论 -
判定二分图和二分图最大匹配
染色法判定二分图#include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N = 1e5+10,M= 2e5+10;int h[N],e[M],ne[M],idx;int color[N];int n,m;void add(int a, int b) { e[idx] = b, ne[idx] = h[a], h[a] = id原创 2021-07-28 11:07:16 · 119 阅读 · 0 评论 -
Prim求最小生成树(朴素版稠密图)
#include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N = 510,INF = 0x3f3f3f3f;int g[N][N],dist[N];bool st[N];int n,m;int prim(){ memset(dist,0x3f,sizeof dist); int res=0; for (int i =原创 2021-07-28 10:00:37 · 180 阅读 · 0 评论 -
已知圆上两点坐标和半径求圆心
牛客题目链接已知两点坐标可求出直线方程,当然也包括斜率了,已知斜率tan a,最近刚学的高数上,可根据三角函数的反函数(C++ atan2(y,x))求出角度(小心为double类型),用到圆心到两点中点这条边可求出圆心。/**遇到此类型的题目就是先确定圆心再去判断其他店是否在圆上或者圆内**/ #include <map>#include <queue>#include <string>#include<iostream>#include&原创 2021-07-24 11:10:46 · 3627 阅读 · 0 评论 -
有边数限制的最短路bellman_ford算法
#include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N = 510,M = 1e4+10;int n,m,k;int dist[N];int back[N];struct Edge{ int a,b,c; }e[M];void bellman_ford(){ memset(dist,0x3f,sizeof原创 2021-07-23 16:35:02 · 153 阅读 · 1 评论 -
稠密图dijkstra模板
#include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N = 510;int g[N][N];int dist[N];bool st[N];int n,m;int dijkstra(){ memset(dist,0x3f,sizeof dist); dist[1] = 0; for (int i = 0; i原创 2021-07-23 16:11:00 · 181 阅读 · 0 评论 -
区间不相同子串个数:字符串哈希
运用了字符串哈希和拉链法实现的哈希题目链接#include <cstdio>#include <cstdlib>#include <cstring>typedef unsigned long long int ULL;//BKDRHash,最优的字符串hash算法。hash一开始是等于0的//for(i=1 to lenstr) hash = seed * hash + str[i]; 这是求解hash值的公式//我们希望,对于任意给定的区间[L,R],原创 2021-07-20 20:55:23 · 219 阅读 · 0 评论 -
UCF Local Programming Contest Round 1A Sum of a Function(区间筛)
典型的区间筛例题,当时不知道这玩意,痛失好题链接:https://ac.nowcoder.com/acm/contest/18428/E#include<iostream>#include<algorithm>#include<vector>using namespace std;const int N = 5e6 + 10;typedef long long LL;int vis[N], pri[N], cnt;LL p[N];bool f[N];原创 2021-07-20 16:39:58 · 168 阅读 · 0 评论 -
双指针 三值字符串
给定一个字符串 s,其中的每个字符都是 1,2 或 3。请你求出同时包含字符 1,2,3 的 s 的最短子串的长度。注意,子串必须是连续的。输入格式第一行包含整数 T,表示共有 T 组测试数据。每组数据占一行,包含一个字符串 s,保证 s 中可能包含字符 1,2 或 3。输出格式每组数据输出一行,一个整数,表示符合条件的最短子串的长度。如果不存在符合条件的子串,则输出 0。数据范围1≤T≤20000,1≤|s|≤2×105,所有 T 个输入字符串的长度之和保证不超过 2×105。输原创 2021-06-04 20:34:39 · 163 阅读 · 0 评论 -
欧拉筛例题
题目描述:小H,他,他想不出来背景了,题意如下。给定两个整数 a,b (a<=b)。令 c=a×(a+1)×(a+2) · · · (b-2)×(b-1)×b ;求 c 中所有质因子的和。结果可能很大,请输出对 109+7 取模的结果。取模运算是求两个数相除的余数。 [1] 取模运算(“Modulus Operation”)和取余运算(“Remainder Operation ”)两个概念有重叠的部分但又不完全一致。 主要的区别在于对负整数进行除法运算时操作不同。取模主要是用于计算机术语中原创 2021-05-30 19:53:39 · 246 阅读 · 0 评论 -
博弈论的一道例题
在前几天的校赛上被一道博弈论的题给干翻了,还是对博弈的过程和必胜态和必败态的分析上没有经验,题目如下:Alice和Bob正在玩n堆石头的游戏。保证n是偶数。 第i堆有 ai 个石头。Alice和Bob轮流玩一个游戏,Alice先手。在每个玩家的回合中,他们必须选择 n/2 个非空的堆,并从每一个被选择的堆中移除数量为正值的石头。他们可以在一个回合中移除不同数量的石头。第一个无法移动的玩家输了(当非空堆少于n/2时)。给定初始数据,决定谁将赢得比赛,输出赢得比赛的人。输入描述:第一行包含一个整数n原创 2021-05-30 16:49:47 · 538 阅读 · 2 评论 -
LCS、LIS
LCS是最长公共子序列的表示:题目链接代码也十分简单就不敲了。LIS是最长上升子序列的英文缩写。(动态规划) O(n2)O(n2)状态表示:f[i]表示从第一个数字开始算,以w[i]结尾的最大的上升序列。(以w[i]结尾的所有上升序列中属性为最大值的那一个)状态计算(集合划分):j∈(0,1,2,…,i-1), 在w[i] > w[j]时,f[i] = max(f[i], f[j] + 1)。有一个边界,若前面没有比i小的,f[i]为1(自己为结尾)。最后在找f[i]的最大值。时原创 2021-05-23 19:55:01 · 563 阅读 · 0 评论 -
动态规划心得
我刚接触动态规划就是背包九讲问题,当时我知道了有DP这种算法,后来也了解接触了区间DP,做题的时候也做了许多DP的题,但是并没有真正的系统学习一下,这次一遍看算法竞赛的动态规划章节一遍巩固一下基础知识。动态规划:我的理解它就像是递推,把大问题分解成许多性质相同的小问题,前面子问题解决的结果可以被后面的问题所调用。一般一个问题具有重复子问题和最优子结构,都大几率是DP。通过对背包问题的学习,我理解了DP就是不断决策选择的问题,背包问题就是有限制的选择,后来做题,发现让求最大值和最小值或者最优方案数的话大几原创 2021-05-23 19:42:28 · 223 阅读 · 0 评论 -
kruskal算法求最小生成树
#include<iostream>#include<algorithm>#include<cstring>using namespace std;const int M = 3000;const int N = 1000;int n, m;struct Edge { int a, b, c; bool operator <(const Edge &t) const { return c < t.c; }}e[M];int原创 2021-05-15 16:33:21 · 172 阅读 · 0 评论 -
序列最大收益
题目在这,一般看到最大值最小值和方案数首先想到的就是DP,看看能不能找到状态表示和转移方程。我当时做题的时候是吧状态表示想到了,但是转移却想不出来,后来发现其实并不难想。,这道跟最长上升子序列十分类似,可以先看最长上升子序列给定一个长度为 m 的整数序列 a1,a2,…,am。序列中每个元素的值 ai 均满足 1≤ai≤n。当一个值为 i 的元素和一个值为 j 的元素相邻时,可以产生的收益为 wi,j。现在,我们可以从序列中删除最多 k 个元素,删除一些元素后,原本不相邻的元素可能会变得相邻。序列原创 2021-05-12 20:19:57 · 153 阅读 · 0 评论 -
spfa(兼判断负环版)
#include<iostream>#include<queue>#include<cstring>using namespace std;const int N=1e5+10;#define fi first#define se secondtypedef pair<int,int> PII;//到源点的距离,下标号int h[N],e[N],w[N],ne[N],idx=0;int dist[N];//各点到源点的距离bool原创 2021-05-10 17:39:55 · 134 阅读 · 2 评论 -
稀疏图Dijkstra堆优化模板
模板得熟练背会#include <iostream>#include <cstring>#include <algorithm>#include<queue>using namespace std;typedef pair<int, int> PII;const int N = 1e6;int e[N],ne[N],h[N],idx;int w[N];int n,m;int dist[N];bool st[N];int原创 2021-05-08 20:33:38 · 189 阅读 · 0 评论 -
哈弗曼树及哈夫曼编码
最近在数据结构课上学习了哈夫曼树及编码,当时听完之后觉得这也不难啊,不就是利用贪心的思想构造了带权路径和最短的树而已,后来去做老师布置的作业之后发现真是写不出来,不知从哪下手。看了慕课上陈越老师讲的之后,发现在每次寻找权值最小的子树合并时用到了堆的概念。堆其实就是优先队列,是一个根节点最小或最大的完全二叉树,每次可以拿出最小的,陈越老师讲解了堆的伪代码。看完视频之后,我感觉更不知道咋写了,赶紧去网上找找大佬写的自己学学压压惊。首先是哈夫曼树的构造,由于哈弗曼树满足带权路径和最短,所以权值小的先构造,权值大原创 2021-05-01 18:15:13 · 389 阅读 · 0 评论