
acm一些基本算法
菜是原罪
鸣蜩二九~
一岁有一岁的味道,一站有一站的风景。
花会沿路盛开,以后的路也是。
展开
-
欧拉函数及其性质与证明
欧拉函数:欧拉函数是求1到n-1中与n互质的数,特殊的 φ(1)=1欧拉通项(也就是公式):其中pi是n的质因子。证明:由于在1到n中pi (也就是质因子) 的倍数是均匀分布的,那么,去掉这些质因子的倍数(占1/pi)就是x * (1 - 1/pi)那么同理,其他质因子也按照这个来,就得到了上述公式求单个欧拉值直接用唯一分解O(sqrt(n))就可以求得欧拉值模板 cin >> n; ll num = n; for(int i = 2;i *原创 2020-12-02 23:06:56 · 2036 阅读 · 0 评论 -
01bfs
题目传送题意:一张 n * m 的地图,上面有空地和墙。给定起点和终点,你可以往上下左右相邻的结点走,但是只能走空地,你也可以用魔法跳到以当前点为中心,5 * 5的范围内的任意空地。要求出走到终点使用魔法的最少次数。思路:我最开始的思路是并查集求连通块(块是一个相互连通的方格区,因为这一块的步数一定是一样的),然后判断从起点块到终点块的最小值,我觉得是没有问题,应该是哪里写错了,导致wa了。后来了解到,这个是典型的01bfs我理解的01bfs是,在最短路中,花费的代价为0和1的时候,要求代价最少原创 2020-08-29 20:15:52 · 1785 阅读 · 0 评论 -
拓展欧几里得求方程整数解和逆元
什么是拓展欧几里得?所谓拓展,就是在欧几里得的基础上得出的推论。拓展欧几里得就是根据欧几里得的原理(辗转相除),可以算出二元一次方程组的整数解和乘法逆元拓展欧几里得:ax + by = c我们知道这个方程组在实数范围内是有无数个解的。但是在整数的范围内他却存在着有限个解。首先介绍裴蜀定理这里再证明一下:为什么在整数解的情况下,c一定是gcd(a,b)的倍数呢?例:2 * x + 4 * y = c那么c无论如何都是偶数,换句话来说,c一定是2的倍数2 = gcd(2,4)3 * x原创 2020-07-24 22:16:06 · 389 阅读 · 0 评论 -
更相减损数
上次做了个题,用到了这个的一点原理,原来以为会用辗转相除法就可以了。。。。更相减损术很简单:古文原文:可半者半之,不可半者,副置分母、子之数,以少减多,更相减损,求其等也。以等数约之。算法思想就是:俩数相减(大减小),然后用减出来的数替换掉大的那个数,然后重复,直到减出来的数和上次的减数相等,则停止,这个数就是俩者的最大公因数。例:12 4第一步:12 - 4 = 8,替换后数为 8 4第二步为:8 - 4 = 4,现在的的减数与减出来的结果相等,那么4就是他们的最大公约数之所以不常用原创 2020-07-10 00:00:53 · 649 阅读 · 0 评论 -
洛谷 - P3390 【模板】矩阵快速幂 (板子)
题目传送题意:板子题,和普通的快速幂差不多,只是变成了矩阵相乘,这里记录下板子AC代码#include <bits/stdc++.h>inline long long read(){char c = getchar();long long x = 0,s = 1;while(c < '0' || c > '9') {if(c == '-') s = -1;c = getchar();}while(c >= '0' && c <= '9')原创 2020-06-28 14:04:18 · 284 阅读 · 0 评论 -
逆元与组合数学的应用
练手题目传送逆元:何为逆元?我们都知道a*b%p无论是先模还是先乘,结果是不变的,但是当a/b%p的时候,先除和先模的结果是不一样的。但是我们在计算组合数学时,又会遇到这种情况(如果不先取模,数据要爆掉),那么逆元便产生了。当a*b%p == 1,那么称b为a%p的逆元费马小定理:假如p是质数,且a,p的最大公约数为1,那么 a^(p-1)%p =1 。即:假如a是整数,p是质数,且a,p互质,那么a的(p-1)次方除以p的余数恒等于1那么我们如何计算a/b呢?由上面已经可得,当p为质数时(原创 2020-06-17 10:29:34 · 467 阅读 · 0 评论 -
树状数组基础操作总结
树状数组用于对区间修改和查询频繁的题树状数组基础操作1.单点修改+区间查询转载大佬的说法模板题模板代码#include <bits/stdc++.h>inline int read(){char c = getchar();int x = 0,s = 1;while(c < '0' || c > '9') {if(c == '-') s = -1;c = getchar();}while(c >= '0' && c <= '9') {x原创 2020-06-10 16:02:20 · 200 阅读 · 0 评论 -
01分数规划算法
例题一例题二基础问题是这样的:现在有n件衣服,每一件都有其价值和价格,现在要求你买k件衣服,使得单位价格内的价值最高01分数规划算法原理:现在假设value为每一件衣服的价值,cost为花费,那么r就是单位价格内价值。现在假设r为单位价格的最大价值,然后我们把r乘过去,然后变换一下得到这时我们再设一个函数f®,自变量只有r,那么有而又因为只有一个自变量,那么现在的xi我们可以看成一个常数,那么我们可以看到 - r* 表示斜率为负,与y轴的截距一定为正,因为价值一定为正,那么我们现在可以原创 2020-06-06 22:42:03 · 479 阅读 · 0 评论 -
单调队列维护数组单调性
模板题一模板题二单调队列是指deque这种双端队列,他既可以从俩端插入也可以删除,基本用法点这里哟那么我们如何维护数组单调性?例8 31 3 -1 -3 5 3 6 7 //求有8个元素的数组在每三个数的区间内的最小值。第一步: 队列为空,那么我们肯定直接先把1加到队尾第二步:3比1大,(我们维护的结果是一个单调递增的序列,我们每次区间最小值为队首),那么3在后面的区间中,还有可能成为最小值(只是可能,如果后面的元素比3小,那么3无论如何都不可能在任意一个区间中成为最小值),我们把其加到队原创 2020-06-04 12:03:14 · 607 阅读 · 1 评论 -
(模板) 埃氏筛 和 欧拉塞塞素数
int ans[10000],vis[10000];for(int i = 2;i <= n;i++){ if(!vis[i]) { ans[m++] = i; for(int j = i;j <= n;j += i) vis[j] = 1; }}//埃氏筛 就是利用素数的倍数一定是合数,来进行塞选int ans[10000],vis[10000];for(int i = 2;i <= n;i++)原创 2020-05-21 23:08:38 · 612 阅读 · 0 评论 -
唯一分解定理及其推论
唯一分解定理:任意一个正整数,都可以分成有限个素数的乘积形式没错,这就是核心,短叭?例如:48 = 2 * 2 * 2 * 2 * 3,54 = 2 * 3 * 3 * 3。代码实现把一个数分解成若干素数的乘积形式:int n;for(int i = 2;i * i <= n;i++) { if(n % i == 0) ...原创 2020-04-29 16:20:38 · 610 阅读 · 1 评论 -
最小生成树 Kruskal算法 板子
比Prim算法更优秀,并且更好理解。但是需要借助并查集的知识并查集算法//如果不清楚并查集,可以去看看这篇,顺便a下板子题Kruskal板子题算法思路先把边按照权值进行排序,用贪心的思想优先选取权值较小的边,并依次连接,判断是否这俩个点连通(用并查集来判断是否存在环)然后继续搜。#include <bits/stdc++.h>using namespace std;#d...原创 2020-04-10 19:03:29 · 253 阅读 · 0 评论 -
最小生成树 Prim算法 + 链式前向星+ 堆优化 板子
初学,听大佬说时间复杂度为O(NlogN)主要是感觉这个板子太简洁了,看起来舒服。。。(在Prim算法中算不错的了)板子题目链接//大佬就不要嘲讽了。我就写着玩的。。。AC代码如果看不懂,可以去题目里面的题解去看,里面的大佬杠杠滴。#include <bits/stdc++.h>using namespace std;#define NewNode (ListNode *...原创 2020-04-07 19:32:55 · 597 阅读 · 1 评论 -
(拓扑排序)以及一点点例题
拓扑排序不止能用于图论中,只要可以转化成入度与出度的问题,都可以转化理解A了它。这里博主初学拓扑,代码就不加注释了,只是当个备忘录。题目传送1//如果初学拓扑,博主这有几个题(不是图论的拓扑,而是拓扑板子加强)。题目传送2题目1 //AC代码#include <bits/stdc++.h>using namespace std;#define NewNode (List...原创 2020-04-06 18:54:23 · 191 阅读 · 0 评论 -
并查集抽象解释
何谓并查集?博主的理解就是,就像小时候打架一样。每个人最开始谁都不服谁,直到有一个人把你打服,那么你就会顺从他,当他的小弟。那么渐渐的,把你打服了的那位老大也可能被别人给收拾了。所以,你的老大不停的更换,你的帮派也在不停的扩大更新。但是,在某时,你肯定是不会为你的对立帮派做事情的。但是,现在有个人就问你,你什么时期是跟的哪位老大呀?你就得回答他(抽象解释。。。)请看题那么,我们现在举例...原创 2020-04-02 16:26:04 · 159 阅读 · 0 评论 -
哈希算法基本介绍(可以推广)
哈希算法是一种便于查找字符串的算法模板传送哈希算法(HASH)其实就是把字符串转化为自己想要的哈希值,这个值由自己的来定义。列如:给你一堆字符串,判断里面有多少个回文字符串,听起来很简单是不是?但是要是这个字符串的数据很大,而且你不能用C++函数的辅助呢?(这里是举个列子哈,毕竟哈希的用处很广)这里就很容易超时,这时候我们就要将每个字符串做出一定的处理,使得判断是否为回文的时候只需要O(1...原创 2020-03-25 19:15:21 · 255 阅读 · 0 评论 -
能输入带空格的函数的简介。
1.首先scanf函数scanf("%[^\n]"),意思是遇到换行符号之前的都读入。2.其次getline函数string str;getline(cin,str);getline读入string类型的字符串空格,属于c++函数。3.还有fgets函数gets函数也能读入空格,但是其没有规定读入多少,所以系统可能会报出溢出风险。fgets函数解决了它,其用法是:char str...原创 2019-11-18 18:25:26 · 1597 阅读 · 1 评论 -
c++ string 函数的用法
string个人认为比c语言的string.h好用多了,功能也全面简洁。首先string类型的字符串可以直接比较 比如:srting s = "SADA",s1 = "SDQW";if(s == s1)......其次string函数里面还有几个函数很好用,先介绍:substr函数,string s;string s1 = s.substr(m,n);意思是让s1赋值为s的第m...原创 2019-11-19 22:01:28 · 155 阅读 · 0 评论 -
set函数的基本用法
map和set的插入删除效率比用其他序列容器高每次insert之后,以前保存的iterator不会失效当数据元素增多时,set的插入和搜索速度变化不大(二分查找)begin() ,返回set容器的第一个元素end() ,返回set容器的最后一个元素clear() ,删除set容器中的所有的元素empty() ,判断set容器是否为空ma...原创 2019-12-15 12:54:18 · 2074 阅读 · 0 评论 -
素数判断
C语言素数判断算法分析1 素数的定义素数:也叫质数,是指大于1,且只能被1和它自身整除的自然数;1既不是素数,也不是合数;2是最小的素数;2 三种算法分析2.1 最简单最易懂的判断方法2,3是质数,直接进行处理;大于3的数,根据素数的定义,从2开始挨个进行求余运算,若中间出现能被整除的数,可判断不是素 数;时间复杂度:O(n);#include <stdio.h>...转载 2019-12-17 10:54:03 · 303 阅读 · 0 评论 -
vector的基本用法
vector相当于一个数组,其大小可以动态改变,在不知道需要存多少元素的情况下,可以节省内存空间。1.基本用法 vector<int>v,v1; v.size()返回其现在存储元素的多少; v.rsize()改变其容量; v.empty()判断向量v是否为空; v.capcity()返回其现在容量大小; v.clear()清空所有元素; v.front()返回第一个元素...原创 2020-01-09 18:09:40 · 227 阅读 · 0 评论 -
单向队列,双向队列,优先队列的基本用法
1.单向队列,意思就是只能从队列后面加入元素,遵循先进先出原则;#include <queue>#include <iostream>using namespace std;int main(){ queue<int>q; q.push(5)//在队列末尾插入一个元素5; q.pop()//删除队列的第一个元素; q.f...原创 2020-01-12 20:29:11 · 1667 阅读 · 0 评论 -
裴蜀定理基本介绍
题目传送门裴蜀定理也叫做(贝祖定理)定理内容:如果方程 ax + by == c,如果x,y的解为整数,那么c一定是gcd(a,b)的倍数。//gcd(a,b)为a,b的最大公约数博主的粗略证明(不知道对不对哈。。。。)当x,y都等于1的时候:a%gcd(a,b) == 0,b%gcd(a,b) == 0.那么(a+b)%gcd(a,b) == 0,而c == a+b;当x,y任意取时...原创 2020-03-11 23:00:09 · 2279 阅读 · 1 评论 -
st表简介以及模板代码
#include <bits/stdc++.h>using namespace std;const int N = 1e5 + 5;const int INF = 0x3f3f3f3f;const double EPS = 1e-10;const int mod = 1e9 + 7;const int II = 3.1415926535;typedef long long...原创 2020-03-12 23:58:02 · 777 阅读 · 0 评论 -
二分查找函数的简介以及手写代码
函数一lower_bound(查找数组的初始地址**//左边界**,查找数组末尾地址**//右边界**,要查找的元素值)//可知我们返回的是一个地址,如果再减去一个数组首地址,则为返回了数组的下标。lower_bound(arr,arr+1+n)-arr.作用 查找到数组中第一个大于等于查找元素的下标。特别的(lower_bound(arr,arr+1+n),x)-arr-1.作用返回最...原创 2020-03-13 20:59:27 · 342 阅读 · 0 评论 -
最大上升子序和
题目传送门最大上升子序和我们这样想,定义一个sum,和Max。sum从数组的第一个元素开始加,由题中我们知道,肯定会存在负数来影响判断。但是,如果当加上一个数组元素,这时的sum(也就是一个子串的和)为负数了。那么肯定对于后面的数(不管后面是啥,一个数加上一个负数,肯定更负)是没有用处的了,所以,前面的这个子段舍弃(sum = 0),然后sum再加上后面的数,继续前面这样的判断。同时你在sum...原创 2020-03-14 22:23:36 · 154 阅读 · 0 评论