算法
文章平均质量分 72
Lopka
大一新生 真.萌新
大四新生 还是萌新
现在工作 依然萌新
展开
-
莫队(sample
思想核心思想就是通过分块算法来减少时间复杂度,从O(n^2)优化到O(nsqrt(n) ),可以解决区间求不同问题思维过程从暴力扫到双指针,动态搜索总是会卡时间复杂度,所以我们为了能尽可能地用上之前的数据,我们选择离线计算后按顺序输出模板加了巨多优化(其中还有许多佛系优化)#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#define maxn 1原创 2020-11-17 22:05:13 · 122 阅读 · 0 评论 -
LCA 最近公共祖先 CodeForces Minimum spanning tree for each edge
LCA基础思想给定一个树/无向图,再给定若干个询问,询问内容是给出两点,要求给出这两点的最近公共祖先。这样子就像两个点各有一条路径回溯到根节点,求这两条路径第一次相交的点在哪里所以最基础的lca,我们就可以找到两条路径,然后找出那个LCA,具体操作就是在一棵树内,标出每个点的深度,然后先把低的那个点跳到高处,然后两个点重合就说明找到LCA,如果不同就一同往上跳,直到找到相同的爹。LCA二进制跳表刚刚那个时间复杂度是O(n^2),所以挺鸡肋的,我们就要用到伟大的二进制,我们知道对于任意一个整数n,它原创 2020-11-17 21:29:26 · 157 阅读 · 0 评论 -
exgcd 拓展欧几里得
拓展欧几里得首先我们要知道一个结论:裴蜀定理(或贝祖定理)存在整数x,y 使得ax+by=gcd(a,b) 成立推导建议拿着笔一起做推导,我们知道欧几里得算法,即辗转相除法,核心公式为gcd(a,b)=gcd(b,a%b),我们就推导出拓展欧几里得。ax1+by1=gcd(a,b)=gcd(b,a%b)=b*x2+(a%b)*y2这样我们就得到了状态转移方程?其中a%b可以写成a-((a/b)*b),我们就得到了最终的状态转移方程,同时因为采取了递归的写法,我们会由2状态推出1状态,原创 2020-11-13 00:34:20 · 249 阅读 · 1 评论 -
第八届蓝桥杯C/C++ B组决赛 发现环
标题:发现环小明的实验室有N台电脑,编号1~N。原本这N台电脑之间有N-1条数据链接相连,恰好构成一个树形网络。在树形网络上,任意两台电脑之间有唯一的路径相连。不过在最近一次维护网络时,管理员误操作使得某两台电脑之间增加了一条数据链接,于是网络中出现了环路。环路上的电脑由于两两之间不再是只有一条路径,使得这些电脑上的数据传输出现了BUG。为了恢复正常传输。小明需要找到所有在环路上的电脑,你能帮助他吗?输入第一行包含一个整数N。以下N行每行两个整数a和b,表示a和b之间有一条数据链接相连。对于3原创 2020-11-09 22:36:31 · 156 阅读 · 0 评论 -
小结线段树
例题——洛谷P3374题目描述如题,已知一个数列,你需要进行下面两种操作:将某一个数加上 x求出某区间每一个数的和输入格式第一行包含两个正整数 n,m分别表示该数列数字的个数和操作的总个数。第二行包含 n 个用空格分隔的整数,其中第 i 个数字表示数列第 i 项的初始值。接下来 m 行每行包含 3 个整数,表示一个操作,具体如下:1 x k 含义:将第 x 个数加上 k2 x y 含义:输出区间 [x,y]内每个数的和输出格式输出包含若干行整数,即为所有操作 2 的结果。输入输出样原创 2020-11-08 14:02:56 · 211 阅读 · 0 评论 -
第九届蓝桥杯C/C++ B组决赛 搭积木dp
题目描述小明对搭积木非常感兴趣。他的积木都是同样大小的正立方体。在搭积木时,小明选取 m 块积木作为地基,将他们在桌子上一字排开,中间不留空隙,并称其为第0层。随后,小明可以在上面摆放第1层,第2层,……,最多摆放至第n层。摆放积木必须遵循三条规则:规则1:每块积木必须紧挨着放置在某一块积木的正上方,与其下一层的积木对齐;规则2:同一层中的积木必须连续摆放,中间不能留有空隙;规则3:小明不喜欢的位置不能放置积木。其中,小明不喜欢的位置都被标在了图纸上。图纸共有n行,从下至上的每一行分别对应积木原创 2020-11-05 18:13:31 · 461 阅读 · 0 评论 -
第九届蓝桥决赛 C/C++ B组 激光样式dp
激光样式x星球的盛大节日为增加气氛,用30台机光器一字排开,向太空中打出光柱。安装调试的时候才发现,不知什么原因,相邻的两台激光器不能同时打开!国王很想知道,在目前这种bug存在的情况下,一共能打出多少种激光效果?显然,如果只有3台机器,一共可以成5种样式,即:全都关上(sorry, 此时无声胜有声,这也算一种)开一台,共3种开两台,只1种30台就不好算了,国王只好请你帮忙了。要求提交一个整数,表示30台激光器能形成的样式种数。思路我看网上大多都是DFS直接暴力,还有一些大佬用二进制状原创 2020-11-04 21:31:23 · 166 阅读 · 0 评论 -
P2925 [USACO08DEC]Hay For Sale S
思路佐田,我在CSDN上学背包问题,有个博主的博客写的特别好啊传送门,我啪的一下就站起来了很快啊,然后上来就是一个01背包例题板子,我大意了啊没有优化,IDE全部防出去了昂,给我来了一发TLE,发生甚么事了?我想怎么回事?哦,原来是少了一个前缀和优化。我优化写了一发交上去了。啊,这时间,按照传统功夫的点到为止来讲,我已经可以下一题了啊,IDE也承认我的优化结果正确,但是我忽然偷袭!点开了题解,我大意了啊没有想到,如果dp【j】==c了之后应该可以直接跳出循环的啊,我劝,年轻人,耗子尾汁,以后做题前要好好反原创 2020-11-03 16:35:30 · 263 阅读 · 0 评论 -
状压DP TSP(状态压缩动态规划)
压缩状态把每种状态做离散化标记.比如一个灯位于(i,j),灯亮的话light[ i ][ j ]=1;不亮就是0. 这个东西选是1不选是0. 这个点走过就是1没走过就是0等等……所以我们把每种状态都可以哈希为一个十进制整数,这个整数根据每个点状态种类的数量不同可以对应转化为二进制、三进制、四进制等等来表示一个状态比如二进制:1001,转化为十进制为9,那么状态[ 9 ]就代表着选四号位,不选三号位,不选二号位,选一号位这一种状态再假设一个人只有三种状态,吃饭 0,睡觉 1,打东东 2,那么三进制:原创 2020-11-01 22:24:11 · 482 阅读 · 0 评论 -
LIS——最长上升子序列 dp+二分优化
朴素O(n^2)建立一个数组res[Maxn], res[ i ]用来记录以i位置为结尾的最长的子序列,那么我们要求res这个数组里的最大值(注意不是res[ n ] ),所以当我们在求res[ i ] 时,需要从0到i-1扫一遍,看看通过哪个点“松弛” (因为这个算法好像迪科斯彻最短路,所以借用这个名词来解释一下),这样代码如下#include<iostream>#include<algorithm>using namespace std;const int MAX=10原创 2020-11-01 14:01:16 · 185 阅读 · 0 评论 -
区间DP入门+优化
区间DP原理先对小区间进行操作得到局部最优解, 然后通过小区间的最优解来得到大区间的最优解。利用了最优子结构和无后继影响的特性。DP模板#include<iostream>#include<algorithm>using namespace std;typedef long long ll;ll dp[2000][2000];int main(){ init(); // 初始化DP for(int len=1;len<=n;len++) // 遍历子原创 2020-10-31 15:43:00 · 732 阅读 · 1 评论 -
树的遍历总结
一.树的遍历方式树的遍历方式按节点数据访问位置分为前序遍历,中序遍历和后序遍历。首先就是,访问左子树和右子树的顺序是一样的,总是 访问左子树->访问右子树,这样很明显,访问当前根节点数据的程序有三个位置可以放,分别是:访问根->访问左子树->访问右子树(前序遍历);访问左子树->访问根->访问右子树(中序遍历);访问左子树->访问右子树->访问根(后序遍历);0.树的定义struct node{ int num; node *l; node原创 2020-10-21 23:01:03 · 325 阅读 · 0 评论 -
蓝桥复习——KMP
KMP在s中寻找p(找到第一次出现的位置)void find_next(char *p){ int h=strlen(p); int k=-1; int j=0; next[j]=k; while(j<h) { if(k==-1||p[k]==p[j]) { j++; k++; next[j]=k; } else k=next[k]; } return ;}int kmp(char *s,char *p){ int hs=strle原创 2020-10-16 23:51:54 · 239 阅读 · 0 评论 -
蓝桥复习——并查集模板
并查集思想我朋友的朋友还是我的朋友记录每个点的父亲,也就是两个点有关系选一个当父亲。先把每个点的父亲设置为自己本身,然后再加入两点有关系时,找到两人的父亲,把两个人的父亲设为父子关系就完成了连通分支的合并。并查集函数int un(int root) //查找父亲{ int son=root; while(root!=pre[root]) root=pre[root]; while(son!=root) { int temp=pre[son]; pre[son]=root;原创 2020-10-16 22:21:43 · 184 阅读 · 0 评论 -
蓝桥杯算法整理第一节 深度优先搜索
DFSDFS原理:递归DFS思想:不撞南墙不回头DFS例题:走迷宫,全排列(等)DFS延伸:记录路径,剪枝模板void DFS(int x,int y){ if(满足所需要的条件) { 相应的操作;return;} else{ for(int i= ; ;) //如果是方向的话,会枚举方向 { 枚举加方向的新坐标; if(界限 :例如:不能出到地图外,原创 2020-10-11 22:23:55 · 575 阅读 · 0 评论 -
线段和最大值
题面给你一串数,从里面任意挑出一串连续排列的数(一个区间),求所有区间数的加和的最大值。思考首先是无脑暴力,直接套i,j,k三个循环,遍历所有可能性即可。但是这样很明显,O(n3)的时间复杂度会让一些较大的数据TLE。所以再思考……接着是前缀和做法,开一个sum数组记录当前位置以及前面所有数的加和,可以省掉for(int k=i;k<=j;k++)的循环,但是O(n2)还是不够满意。所以再思考……接着是想,符合条件的区间会满足怎么样的特性呢?首先是,满足条件的区间(和最大的那个),左右两端(原创 2020-09-10 18:42:25 · 992 阅读 · 0 评论 -
线段树听课学习笔记
一.线段树的引入做题的时候遇到了BMQ问题,就是求给定区间中的最大值最小值问题,暴力搜索只限于数据范围较小,控制在1000-10000左右的时候。而线段树解决了O(nlogn)的时间复杂度,其中建树为O(n).二.线段树的性质1.平衡二叉树,最大深度为logn2.树中每一个节点代表一个区间(叶子节点是一个点)3.每个节点完全包含他的所有子孙节点4.任意两个节点要么是完全包含,要么互不相交5.在进行区间操作和统计时把区间等价转换为若干个子区间的相同操作三.区间和例子#include<i原创 2020-08-30 20:32:42 · 120 阅读 · 0 评论 -
怪盗——1412(排列组合
题目描述一个长度为n+m+k包含n个数字1,m个数字2和k个数字4的数组,最多可能有多少个子序列1412?如果一个序列是数组的子序列,当且仅当这个序列可以由数组删去任意个元素,再将数组中的剩余元素按顺序排列而成。输入描述:第一行一个整数t,表示测试用例的组数。接下来{t}t行每行三个整数n,m,k表示一组测试用例。输出描述:对于每组测试用例输出一行一个整数表示答案。示例1输入36 7 81 2 26 0 3输出50400备注:{1<=t<=200000}1&原创 2020-05-23 02:05:47 · 458 阅读 · 0 评论 -
Dis2(distance2)
题目描述给出一颗n个点n−1条边的树,点的编号为{1,2,…,n-1,n}1,2,…,n−1,n,对于每个点i(1<=i<=n),输出与点{i}i距离为{2}2的点的个数。两个点的距离定义为两个点最短路径上的边的条数。输入描述:第一行一个正整数{n}n。接下}n−1行每行两个正整数u,v表示点u,v之间有一条边。输出描述:输出共n行,第i行输出一个整数表示与点i距离为2的点的个数。样例输入41 22 33 4输出1111题目分析其实这道题也不是很难,主要原创 2020-05-23 01:47:03 · 705 阅读 · 0 评论 -
矩阵相乘·(离散数学我再也不怕啦
直接上代码#include<iostream>using namespace std;int n;class node{ public: int data[20][20]; int size; node() //无参构造 { size=0; } node(const node & a) //带参构造 { this->size=a.size; int limit=a.size; for(int i=0;i<limit;i++)原创 2020-04-11 21:51:43 · 2908 阅读 · 0 评论 -
高精度乘法(High precision multiplication
Background IntroductionBulls are so much better at math than the cows. They can multiply huge integers together and get perfectly precise answers … or so they say. Farmer John wonders if their answers are correct. Help him check the bulls’ answers. Read i原创 2020-01-14 16:53:27 · 286 阅读 · 0 评论 -
BFS 经典问题 走迷宫
题目描述定义一个二维数组:int maze[5][5] ={0, 1, 0, 0, 0,0, 1, 0, 1, 0,0, 0, 0, 0, 0,0, 1, 1, 1, 0,0, 0, 0, 1, 0,};它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。输入描述一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。输出描述左上角到右下角的最短路径,格式如样例所示。样例输入0 1 0 0原创 2019-12-05 23:17:21 · 255 阅读 · 0 评论 -
BFS的模板以及理解&& 经典油田连通块问题
BFS(Breadth First Search)宽度优先搜索这是一种分层搜索的算法,即从出发点先搜索一遍一步就能到达的点,然后再拿这些找到的点再做一次这样的操作,知道不符合要求,或者所有的结点都扫了为止模板#include<cstdio>#include<queue>using namespace std;void bfs(int a);{ queue<类型> q;//定义一个队列 q.push(a);//可以把队列看成一把枪,push就是把子弹压入原创 2019-12-05 14:52:44 · 321 阅读 · 0 评论 -
欧拉筛(线性筛 代码实现以及理解以及重要步骤的证明
欧拉筛(线性筛老办法,我们先来看看埃式筛一.埃式筛埃式筛运用的是一个很简单的算法,“一个素数的整数倍一定是一个合数”,运用这个办法,我们来编写一下埃式筛的程序const int n = 1000000;int prime[1000010];//用来存放素数void aishishai() { int i, j; for (i=0; i<n; i++)//方便理解,是素数的初值附为1 prime[i] = 1; prime[0] = prime[1]原创 2019-12-02 14:24:50 · 933 阅读 · 7 评论