![](https://img-blog.csdnimg.cn/20190918135101160.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
算法-洛谷
记录洛谷试炼场刷题日常
DongLUOWAN
这个作者很懒,什么都没留下…
展开
-
洛谷1177-归并排序--C++(归并排序)
归并排序的步骤就是先划分,再把两部分进行两两合并,合并的时候就用到了归并排序。归并排序是一个稳定的排序,算法的时间效率是O(nlgn),空间效率是O(n),是一个比较好的排序。AC代码#include<iostream>using namespace std;const int N=100010;int a[N];int n;void merge(int l,int r,int mid){ int tmp[N]={0}; int lpos=l,rpos=mid+1,pos=l;原创 2022-03-29 20:21:36 · 1235 阅读 · 0 评论 -
洛谷1835-素数密度-C++-(欧拉筛)
对于这种快要移溢出但是又没有溢出的数据范围,一律开long long,索引越界了,调试了一个小时。有一个测试点r=2147483647,加1就越界了,循环停不下来了:(难受AC代码#include<iostream>#include<cmath>using namespace std;typedef long long LL;const int N=1e6+10;int l,r;int a[N],prime[N],visit[N],cnt;void Euler(原创 2022-03-23 18:01:50 · 932 阅读 · 0 评论 -
洛谷1069-细胞分裂-C++-(质因数分解)
AC代码本质上是分解质因数和一层覆盖关系,调试了几个小时,问题出在数组越界,难受死我了,不过最后还是AC了。#include<iostream>using namespace std;#define inf 0x3f3f3f3fconst int N=10010;int n,m1,m2;int s[N];//底数的质因数分解int base[200][2],cnt;//培养皿的质因数分解int tbase[100010][2],tcnt;void mysplit(int原创 2022-03-23 01:01:03 · 665 阅读 · 0 评论 -
洛谷3601-签到题-C++-(欧拉函数)
欧拉函数模板:对于某一个数n,我们要求小于n并且与 n互质的数的个数,我们就可以用欧拉函数来求解。phi(n)=n×(1-1/p1)×(1-1/p2)×…×(1-1/pk),其中p是小于n的质因数,这里我们可以联想整数的质因数分解定理,枚举1~sqrt(n)的所有质数,更改其欧拉函数值,同时缩小n,如果最后的值大于1,则再改变一次即可。#include<iostream>using namespace std;#define mod 666623333#define N 100原创 2022-03-22 22:24:43 · 1322 阅读 · 0 评论 -
洛谷3388-割点-C++ && python-(tarjan割点算法)
AC代码C++#include<iostream>#include<vector>using namespace std;#define N 20010int n,m;int dfn[N],low[N],vis[N],tim=1;int flag[N],u,v;vector<int> point[N];int min(int x,int y){ return x>y?y:x;}void tarjan(int cur,int far){原创 2022-03-21 16:27:04 · 1825 阅读 · 0 评论 -
洛谷1443-马的遍历-python-(BFS)
AC代码if __name__=="__main__": n,m,x,y=map(int,input().split()) MAP=[[-1 for i in range(m+1)] for j in range(n+1)] visit=[[0 for i in range(m+1)]for j in range(n+1)] MAP[x][y]=0 visit[x][y]=1 dx=[-1,-2,-2,-1,1,2,2,1] dy=[2,1,-1原创 2022-03-19 08:28:26 · 512 阅读 · 0 评论 -
洛谷1092-最大公约数与最小公倍数-python-(gcd)
此题注意一定要对枚举的数进行预处理,确保这个数是x的倍数,是y的因子,这样枚举就不会超时。AC代码def gcd(x,y): return x if y==0 else gcd(y,x%y)x,y=map(int,input().split())ans=[]for i in range(x,y+1): if i%x==0 and y%i==0: ans.append(i)lth=len(ans)cnt=0for i in range(lth): fo原创 2022-03-17 18:33:27 · 643 阅读 · 0 评论 -
洛谷3865-ST表模板-C++-(ST表+倍增)
AC代码关于这个代码,调了大半天,最后错在运算符优先级上,真的服了自己。对于j+1<<(i-1)这一段语句,我原本想的是 j加上2^(i-1), 但是运算的结果却是(j+1)^(i-1),导致代码一直出错。😦 难受的一个晚上希望在以后的代码过程中能够避免此类错误。#include<iostream>#include<algorithm>#include<math.h>using namespace std;#define N 100010#原创 2022-03-16 00:02:13 · 913 阅读 · 0 评论 -
洛谷3379-LCA-C++-(LCA+倍增)
由于python超时了四五个点,所以用C++写了一下AC代码#include<iostream>#include<vector>using namespace std;#define N 500010int n,m,s;int vis[N],far[N][20],dep[N];vector<int> point[N];void dfs(int root,int deep){ dep[root]=deep; vis[root]=1; for(int原创 2022-03-15 13:04:06 · 1461 阅读 · 0 评论 -
洛谷3366-最小生成树-python-(kruskal+并查集)
TLE3个点的代码,没办法,python循环太慢了。#克鲁斯卡尔global n,mglobal sideglobal parentdef find(x): while parent[x]!=-1: x=parent[x] return xdef kruskal(): ans=0 #找到n-1条边就退出循环 count=0 for i in range(m): u,v,w=side[i][0],side[i][1],原创 2022-03-15 10:52:43 · 827 阅读 · 0 评论 -
洛谷3366-最小生成树-python-(prim算法)
70分代码,python超时了# primglobal n,m,side,pointglobal lowcost,clostdef prim(sta): lowcost[sta],lth=0,len(point[sta]) for i in range(lth): u,v,w=side[point[sta][i]][0],side[point[sta][i]][1],side[point[sta][i]][2] if v!=sta:原创 2022-03-14 21:46:45 · 493 阅读 · 0 评论 -
洛谷1257-最近的两个点-python-(优化算法)
AC代码import mathglobal msgdef solution(left,right): dis=float("inf") #递归终点 if left==right: return dis elif left+1==right: return distance(msg[left],msg[right]) mid=(right+left)//2 d1=solution(left,mid) d2=原创 2022-03-14 19:33:36 · 687 阅读 · 0 评论 -
洛谷4779-最短路优化-python-(手搓二叉堆+dijkstra)
"""堆优化+dijkstra"""class node: def __init__(self,val,idx): self.val=val self.idx=idxclass heap: arr=[] def __init__(self,s=None): if s!=None: self.arr.append(s) def change(self,x,y): s原创 2022-03-12 10:40:18 · 607 阅读 · 1 评论 -
洛谷2085-最小函数值-python-(二叉堆)
最近在学习dijkstra最短路算法,朴素算法的时间复杂度是O(N^2),也就是说当数据量达到1e5的时候,1S可能就不够了,因此我们需要对算法进行优化,如果能让时间复杂度变为O(NlogN)的话,一般来说能过所有的dijkstra最短路相关的问题,那么我们如何进行优化呢?我们知道dijkstra算法外面一层循环,里面两个循环,范围都是1~n,外面循环一次就确定一个最短路径的长度,这是不能够去优化的,因此我们想到优化内部的循环。内部算法的目的是找到一个还未被访问,并且单源路径最短的一个点,并且对这个点所能原创 2022-03-11 21:58:49 · 1016 阅读 · 0 评论 -
洛谷1434-滑雪-python-(记忆化搜索+dfs)
什么是记忆化搜索呢?搜索的低效在于没有能够很好地处理重叠子问题;动态规划虽然比较好地处理了重叠子问题,但是在有些拓扑关系比较复杂的题目面前,又显得无奈。记忆化搜索正是在这样的情况下产生的,它采用搜索的形式和动态规划中递推的思想将这两种方法有机地综合在一起,扬长避短,简单实用,在信息学中有着重要的作用。记忆化搜索,我们在dfs过程中对于一已经搜索过的点,就不必再去搜索,直接返回,大大提高了搜索的效率相比于常规的dfs算法,不用一条路搜到底,我们只需要在之前搜索过的点停止搜索即可。python代码我们在原创 2022-03-10 20:13:27 · 639 阅读 · 0 评论 -
洛谷5788-单调栈模板-C++-(单调栈)
AC代码#include<iostream>#include<stack>using namespace std;int n;int a[3000010],res[3000010];struct node{ int value; int index;};int main(){ stack<node> mystack; node tmp; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("原创 2022-03-07 22:23:46 · 484 阅读 · 0 评论 -
洛谷3397-地毯-C++-(二维差分+二维前缀和)
#include<iostream>using namespace std;int n,m;int x1,y1,x2,y2;int mp[1010][1010],presum[1010][1010];int main(){ cin>>n>>m; while(m>0){ cin>>x1>>y1>>x2>>y2; mp[x1][y1]+=1; mp[x2+1][y1]-=1; mp[x1][y原创 2022-03-06 21:43:24 · 522 阅读 · 0 评论 -
洛谷3368-树状数组-C++-(差分+树状数组模板)
一般来说,树状数组在做单点修改,区间查询操作的效率是比较高的,所以当我们遇到一个数组,要对其进行多次的某个位置上的值的修改时,或者查询一段区间的值的和的查询时,我们优先考虑树状数组。但是,当我们要进行单点查询和区间修改时,可以引入差分,这时,区间修改就是两次单点修改,单点查询就是一次区间查询差分的学习链接#include<iostream>using namespace std;typedef long long ll;ll a[500010];int s,x,y,k;int n,原创 2022-03-05 12:06:43 · 447 阅读 · 0 评论 -
洛谷3371-最短路-python-(dijkstra+floyd)
著名的最短路算法包括dijkstra,floyd,SPFA,本次代码主要是前两种,SPFA算法版之后更新"""dijkstra"""global side,pointglobal visit,dis,pdef dijkstra(n,s): visit[s]=True p[s]=s dis[s]=0 for i in range(len(point[s])): sd=point[s][i] v=side[sd][1]原创 2022-03-03 22:00:08 · 386 阅读 · 0 评论 -
洛谷3807-卢卡斯定理-python-(lucas+费马小定理+快速幂)
*AC代码global n,m,pdef fast_pow(a,b): ans=1 while b: if b&1: ans=(ans*a)%p a=(a**2)%p b>>=1 return ansdef getCombination(a,b): if b>a: return 0 if b>a-b: b=a-b u=1原创 2022-03-02 21:37:22 · 545 阅读 · 0 评论 -
洛谷1908-逆序对-python-(树状数组+离散化)
#树状数组模板global treeglobal n,rank#返回末尾的第一个1的位置#也就是的到下一个要查询的点的位置def lowbit(x): return x&(-x)def query(x): ans=0 while x: ans+=tree[x] x-=lowbit(x) return ansdef add(index,k): while index<=n: tree[ind原创 2022-02-28 17:39:39 · 394 阅读 · 0 评论 -
洛谷2004-领地选择-python-(二维数组的前缀和)
推荐学习视频n,m,c=map(int,input().split())gra=[0 for i in range(n)]for i in range(n): gra[i]=list(map(int,input().split())) #矩阵数组dp=[[0 for i in range(m)]for j in range(n)]dp[0][0]=gra[0][0]for i in range(1,m): dp[0][i]=dp[0][i-1]+gra[0][i]fo原创 2022-02-28 13:36:54 · 411 阅读 · 0 评论 -
洛谷1807-最长路-python-(拓扑排序+dp)
AC代码n,m=map(int,input().split())if m==0: print(-1)else: side=[0]*m point=[[] for i in range(n+1)] rud=[0]*(n+1) dp=[-float("inf")]*(n+1) for i in range(m): side[i]=list(map(int,input().split())) point[side[i][0]]原创 2022-02-27 23:16:42 · 286 阅读 · 0 评论 -
洛谷3916-图的遍历-python-(tarjan强连通分量算法+缩点+图的重建+dfs算法)
题目要求我们求出从每一个点出发所能到达的点的最大值思路1:对每一个点采用dfs搜索,求出最大点的编号。这样从理论上来说是可行的,但是时间复杂度是O(n^2),肯定是会超时。思路2:对原图进行缩点,每一个强联通分量都看成一个点,连接这几个点,然后进行dfs,求出每一个点能够到达的最大值作为这一个强连通分量的最大值,最后就是输出答案了。这里采用思路2来进行解题:①如何求出一张图的强连通分量tarjan算法def tarjan(v): global time,num vis[v]=1原创 2022-02-27 16:34:46 · 676 阅读 · 0 评论 -
洛谷3884-二叉树问题-python-(dfs+bfs+lca+倍增)
对于一个二叉树来讲,我们通常的问题一般有一下几种:①求解二叉树的深度②求解二叉树的宽度③求解两个结点最近的公共祖先下面就利用一些算法来实现以上的要求该代码存储树结点的数据结构主要是利用嵌套列表,即每一个结点都用一个列表存储,列表内一共有四个元素,分别是该结点的左孩子结点,该结点的右孩子结点,该结点的父亲结点,该结点的深度。对于题目中的数据的存储方式的代码n=int(input())tree=[[0 for j in range(4)] for i in range(n+1)]#用列表来存储原创 2022-02-24 19:43:03 · 573 阅读 · 0 评论 -
洛谷1536-村村通-C-(并查集)
并查集AC代码#include<stdio.h>int parent[1010];int n,rel,x,y;int find(int x){ int t_val=x; while(parent[t_val]!=-1) t_val=parent[t_val]; return t_val;}void union_xy(int x,int y){ int root_x=find(x); int root_y=find(y); if(root_x!=root_y){原创 2022-02-23 00:27:52 · 188 阅读 · 0 评论 -
洛谷3372-线段树1-python-(线段树)
看注释global n,m,nums,MAX_LENS,treeMAX_LENS=10000#树存储结构tree=[0]*MAX_LENS#懒惰标记存储结构lazy_tag=[0]*MAX_LENS#建树def build_tree(node,sta,end): if sta==end: tree[node]=nums[sta] return mid=(sta+end)//2 left_node=2*node+1 righ原创 2022-02-21 16:48:07 · 638 阅读 · 0 评论 -
洛谷1102-A-B对-C++-(二分查找细节)
对于一个有序的数组,我们要查找一个元素,假设值为value,我们需要求出这个有序的数组中有几个value值,这个时候我们怎么做?首先找到第一个值为value的值,再找出第一个值不为value的值,两者下标相减即可找第一个值为valueint find_1(int l,int r,int value){ while(l<=r){ int mid=l+(r-l)/2; if(value<=a[mid]){ r=mid-1; } else{ l=mid+1; }原创 2022-02-12 14:04:28 · 634 阅读 · 0 评论 -
洛谷1498-谢尔宾斯基三角形-python-(递归)
这题乍一看很简单,就是在三角形内绘制三角形。找到三角形的三个点连接即可。但是运行的过程不可能是通过画图来完成的啊,用编程语言实现起来还是比较麻烦的。输入一个n,我们通过看题可以得知,输出图形的高度为2n,宽度为2(n+1)。所以我们初始就要定义一个与此维度相当的数组利用列表推导式即可n=int(input())msg=[[" " for i in range(2**(n+1))] for j in range(2**n)]接下来我们就要对这个题目进行分析了:我们要输出,输出是一行一行的,所以我原创 2022-02-11 16:51:43 · 841 阅读 · 0 评论 -
洛谷1593-幂次方因子和-C++-(快速幂+乘法逆元+等比数列+分解质因数)
1原创 2022-02-09 22:52:54 · 881 阅读 · 0 评论 -
洛谷1157-组合数-python-(回溯算法)
这次python AC了!!组合问题相较于全排列问题,在于每一次递归的初始位置,排列问题每次都是从头开始查找满足条件的数,但是组合问题查找是从上一次循环的下一个位置开始的,这点需要注意!visit=[0]*20result=[0]*20def dfs(n,r,sta,deep): if deep==r: for i in range(r): print("{:>3}".format(result[i]),end="") print原创 2022-02-03 22:17:52 · 840 阅读 · 1 评论 -
洛谷1591-n的阶乘中某数出现的次数-C++-(高精度乘法)
AC代码#include<iostream>#include<string.h>#include<math.h>using namespace std;int t,n,a;int res[2570]={0};void init(){ res[0]=1;}//计算1000!大概有几位 2568void countwei(int n){ double ans=0; for(int i=1;i<=n;i++) ans+=log10(i);原创 2022-02-01 23:02:12 · 1005 阅读 · 0 评论 -
洛谷1591-n的阶乘中某数出现的次数-python-(高精度乘法)
这个题用python写,全部超时我们为了得到1000!的位数,可以通过如下计算:我们不妨设1000!的位数为k位,我们可以知道10^(k-1)< 1000!< 10 ^(k),两边取log10,可以计算出k的范围import math#计算位数 大概2600位def count(n): ans=0 for i in range(1,n+1): ans+=math.log(i,10) return ansdef highMult(n,a):原创 2022-02-01 23:01:12 · 1193 阅读 · 0 评论 -
洛谷1923-第k小-C-(快速排序+分治算法)
AC代码#include<stdio.h>int a[5000000];int n,k;int deal(int a[],int l,int r){ int temp=a[l]; while(l<r){ while(l<r && a[r]>=temp){ r-=1; } a[l]=a[r]; while(l<r && a[l]<=temp){ l+=1; } a[r]=a[l]; }原创 2022-01-29 18:03:48 · 736 阅读 · 0 评论 -
洛谷1923-第k小-python-(快速排序+分治算法)
既然选择了python,就要承担超内存的风险。def deal(arr,l,r): temp=arr[l] while l<r: while l<r and arr[r]>=temp: r-=1 arr[l]=arr[r] while l<r and arr[l]<=temp: l+=1 arr[r]=arr[l] arr[l]=temp原创 2022-01-29 18:03:01 · 1272 阅读 · 0 评论 -
洛谷1045-麦森数-C++-(快速幂+高精度乘法)
AC代码#include<iostream>#include<math.h>#include<string.h>using namespace std;int ans[501]={0},bot[501]={0};void init(){ ans[0]=1; bot[0]=2;}void mult1(){ int res[501]={0}; for(int i=0;i<500;i++){ for(int j=0;j<500-i;j++原创 2022-01-28 21:58:06 · 739 阅读 · 1 评论 -
洛谷1045-麦森数-python-(快速幂+高精度乘法)
既然选择了python,就要承担超时的风险,过了三个点#快速幂算法+高精度乘法import mathans=[0]*501bot=[0]*501ans[0]=1bot[0]=2#计算位数def count(n): return int(math.log10(2)*n)+1#快速幂算法def fast_pow(a,b): ans=1 while b: if b%2==1: mult1() mult2()原创 2022-01-28 21:30:51 · 731 阅读 · 0 评论