
算法进阶指南
AKone123456
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
数独----------------------------思维(dfs+优化策略)
#include<bits/stdc++.h>using namespace std;const int N=9;char str[N*N+10];int col[N],row[N],cel[3][3];//col,row存放每列每行应对的二进制位 。 cel[3][3]存放的是每一个3*3的矩阵状态。//需要哪一块只需要cel[x/3][y/3]就行了 int ones[1<<N],mp[1<<N];//统计有多少个1.每个1对应到哪一位 inline..原创 2020-05-27 23:50:20 · 250 阅读 · 0 评论 -
银河英雄传说----------------------------------思维(并查集)
解析:对于两个战舰之间的战舰的数量用一个数组记录,压缩路径的同时更新这个数组即可#include<bits/stdc++.h>using namespace std;const int N=3e4+1000;int fa[N];int s[N],d[N],a,b;int t;int find(int x){ if(x!=fa[x]) { int root=find(fa[x]); d[x]+=d[fa[x]]; ..原创 2020-05-27 14:44:58 · 208 阅读 · 0 评论 -
程序自动分析-----------------------------思维(并查集+离散化)
解析:由于i,j非常大,所以我们需要离散化一下先把相同的加入到集合中,然后再去找不同的判断不同的两个数是否在同一集合中#include<bits/stdc++.h>using namespace std;const int N=1e6+10;struct node{ int x,y,f; }res[N];int a[N],b[N];int fa[N];int t,n;int find(int x){ if(x!=fa[x]) fa[x]=fin..原创 2020-05-26 16:31:43 · 189 阅读 · 0 评论 -
可达性统计------------------------------思维(拓扑排序+dp)
解析:由题意可知是一个有向无环图 DAG,所以我们做一遍拓扑排序。然后根据dp的思想f(u)= f(u1) ∪ f(u2) ∪ f(u3)对于想要求解出u的情况。必须把u1,u2,u3求解出来。所以我们倒着遍历拓扑排序后的数组。然后借助bitset数组统计1的情况即可#include<bits/stdc++.h>using namespace std;const int N=3e4+10;bitset<N> f[N];vector<int> G[N..原创 2020-05-25 23:10:25 · 227 阅读 · 0 评论 -
内存分配-----------------------------思维(模拟)
#include <iostream>#include <algorithm>#include <queue>#include <set>#include <vector>using namespace std;typedef pair<int, int> PII;int n;queue<PII> waits; // (first: 内存长度,second: 占用时间)set<...原创 2020-05-25 22:43:18 · 174 阅读 · 0 评论 -
奶牛矩阵--------------------------------------思维(kmp)
解析:字符串最长为75,所以我们可以枚举列的最小循环节(暴力枚举)但是我们不能枚举行的最小的循环节,因为n太大了。所以我们利用kmp求解行的最小循环节即可#include<bits/stdc++.h>using namespace std;const int N=1e5+1000;char s[N][80];bool st[N];int ne[N];int n,m;int main(){ cin>>n>>m; memset(st,false..原创 2020-05-25 21:23:16 · 239 阅读 · 0 评论 -
矩阵---------------------------------------------思维(二维hash模板)
解析:二维哈希模板Sp[b]-hip[a*b]+h[j]#include<bits/stdc++.h>using namespace std;typedef unsigned long long ull;const int N=1e6+1000;int n,m,a,b,q;char str[20005];ull h[3005][3005];ull p[N];ull P=131;ull get(ull f[],int l,int r){ return f[r]-f[..原创 2020-05-23 16:17:44 · 203 阅读 · 0 评论 -
匹配统计----------------------------思维(二分+hash)
解析:把A和B串哈希。然后枚举A串的后缀,然后二分A串和B串匹配的长度即可时间复杂度O(nlogn)#include<bits/stdc++.h>using namespace std;typedef unsigned long long ull;const int N=2e5+10000;char a[N],b[N];ull P=131;ull h1[N],p1[N],h2[N],p2[N];int n,m,q,x;int cnt[N];ull get_h1(int..原创 2020-05-23 11:41:25 · 211 阅读 · 0 评论 -
树形地铁系统-----------------------思维(树的最小表示法)
解析:树的最小表示法:对于每个节点的最小表示法为子节点的最小表示法排序连接起来最终都是通过排序连接。0表示向下走,1表示向上走#include<bits/stdc++.h>using namespace std;string dfs(string &seq, int &u){ u ++ ; vector<string> seqs; while (seq[u] == '0') seqs.push_back(dfs(seq, u)...原创 2020-05-23 11:06:31 · 274 阅读 · 0 评论 -
黑盒子--------------------------------思维(对顶堆)
#include<bits/stdc++.h>using namespace std;const int N=1e5+10;int a[N],b[N];int n,m;int main(){ scanf("%d %d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=m;i++) scanf("%d",&b[i]); pr...原创 2020-05-22 00:46:18 · 224 阅读 · 0 评论 -
项链----------------------------------思维(最小表示法)
解析:因为项链是环形,且还要输出字典序最小的。那么满足最小表示法的性质所以我们对这两个串求最小表示法比较这两个串的最小表示法是否相同即可#include<bits/stdc++.h>using namespace std;const int N=1e6+1000;char a[N],b[N],s[N*3];int n;void calc(char a[]){ for(int i=0;i<2*n;i++) s[i]=a[i%n]; int i=0,j..原创 2020-05-22 00:05:01 · 169 阅读 · 0 评论 -
城市游戏--------------------------思维(单调队列)
解析:这道题是"直方图中最大的矩形"的升级对于这个二维数组,我们枚举每一行。对于每一行的每一列统计一下,从i行~1行连续的F的个数,作为h[i][j]的高度。就转变成"直方图中最大的矩形“的题目了,我们只要用单调队列去维护当前i向左扩展能扩展到哪个位置上,向右扩展能扩展到哪个位置上。那么这个面积就是:a[i]*(right-left+1)依次枚举即可#include<bits/stdc++.h>using namespace std;const int N=1005;ch..原创 2020-05-21 20:18:45 · 203 阅读 · 0 评论 -
小猫爬山--------------------------思维(dfs)
#include<bits/stdc++.h>using namespace std;int cat[20],sum[20];int n,k,w,ans=20;void dfs(int u,int k){ if(k>ans) { return ; } if(u==n) { ans=k; return ; } for(int i=0;i<k;i++) { ..原创 2020-05-20 14:06:01 · 250 阅读 · 0 评论 -
表达式计算4---------------------思维(栈)
#include<bits/stdc++.h>using namespace std;stack<int> num;stack<char> ops;int qmi(int b,int a){ int res=1; while(a--) { res=res*b; } return res;}void cal(){ int a=num.top();num.pop(); int b=num.top();num.pop(); char c=.原创 2020-05-20 13:45:02 · 256 阅读 · 0 评论 -
数据备份-----------------------------思维(set+双链表)
#include<bits/stdc++.h>using namespace std;typedef long long ll;typedef pair<ll,int> PIL;const int N=1e5+1000;int n,k;ll l[N],r[N],d[N];set<PIL> s;void delet(int p){ r[l[p]]=r[p]; l[r[p]]=l[p];}int main(){ cin>>n&g...原创 2020-05-20 10:24:38 · 182 阅读 · 0 评论 -
荷马史诗----------------------------思维(k叉哈夫曼树)
#include<bits/stdc++.h>using namespace std;#define x first#define y secondtypedef long long ll;typedef pair<ll,int> PII;int n,k;int main(){ cin>>n>>k; ll x; priority_queue<PII,vector<PII>,greater<PI..原创 2020-05-19 23:30:36 · 225 阅读 · 1 评论 -
括号画家---------------------思维(栈)
解析:用栈实现去匹配。如果匹配成功的出栈,那么对应的长度分为两种第一种:栈里面还有元素,那么长度就是(i-当前栈里未能匹配成功的最后一个字符下标)第二种:栈空了,说明从0~i这一段都是美观的。长度为i+1两者取较大值即可#include<bits/stdc++.h>#include<algorithm>using namespace std;const int N=1e6+10;char s[N];int main(){ cin>>s;..原创 2020-05-19 10:00:22 · 231 阅读 · 0 评论 -
最长异或值路径--------------------------思维(字典树+性质)
解析:性质:在一棵树上任意两点的异或距离就是 f(a,root) ^ f(b,root) ^ f(lca(a,b),root) ^ f(lca(a,b),root)因为后面两个一样所以公式就变为:f(a,root) ^ f(b,root)我们只要dfs一遍求出每个节点的到根的异或值。然后就转化成任选两个点异或值最大。那就是交给字典树了#include<bits/stdc++.h>using namespace std;const int N=1e6+1000;typedef ..原创 2020-05-18 13:32:06 · 267 阅读 · 0 评论 -
序列-------------------------------思维(二叉堆)
解析:两步走:第一步: 因为存在很多行,不能暴力合并匹配。我们可以先求出第一第二行合并后的m个最小值。然后用求出来的这个数组再去和下面的数组合并 一共会进行m-1次操作第二步: 怎么选出m个最小值呢,当然n2 做法是不可取 。所以我们利用分组+二叉堆可以O(mlogn) 求出假设现在只有2行a1,a2,a3…amb1,b2,b3…bm我们给a数组排序,然后分组a1+b1,a2+b1,a3+b1…am+b1a1+b2,a2+b2,a3+b2…am+b2…a1+bm,a2+bm,a..原创 2020-05-18 11:33:21 · 234 阅读 · 0 评论 -
超市---------------------------------------思维(二叉堆+贪心)
解析:首先对商品按照过期时间从小到大排序,相同时间按照利润大的排到前面。然后遍历,放到堆里面。如果放的物品个数大于当前商品的过期时间,需要弹出堆(因为你不可能2天时间买3个物品)#include<bits/stdc++.h>using namespace std;#define x first#define y secondconst int N=1e5+10000;typedef pair<int,int> PII;PII q[N];int n;int ..原创 2020-05-18 10:33:37 · 175 阅读 · 0 评论 -
后缀数组----------------------------模板(hash+二分+最长公共前缀)
对于SA数组SA[i]=i:表示 i~n的后缀 的起始位置为i对于最长公共前缀我们可以hash+二分求解出来对于SA数组的排序,可以根据最长公共前缀后一个字符作为关键字比较#pragma GCC optimize(3,"Ofast","inline")#include<bits/stdc++.h>using namespace std;typedef unsigned long long ull;const int N=1e6+1000;ull h[N],p[N],P=13..原创 2020-05-16 11:17:38 · 261 阅读 · 0 评论 -
周期--------------------------------思维(kmp+最小循环节)
解析:kmp+最小循环节最小循环节 :n-next[n]循环次数:n/(n-next[n])本题只要一位一位去匹配计算即可#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>using namespace std;const int N=1e6+10;int f[N];int n,k;char s[N];void init(){ for..原创 2020-05-16 11:32:32 · 170 阅读 · 0 评论 -
回文子串的最大长度---------------------------------思维(马拉车)
#include<bits/stdc++.h>using namespace std;const int N=3e6+1000;int p[N];char s[N];char str[N];int n,len;void get_str(){ int k=0; str[k++]='@'; for(int i=0;i<n;i++) { str[k++]='#'; str[k++]=s[i]; } str[k++]='#'; str[k]=0; len=.原创 2020-05-15 13:28:04 · 181 阅读 · 0 评论 -
雪花雪花雪花----------------------------------思维(最小表示法)
解析:由两种操作:1.翻转2.旋转旋转可以把第n个位置移到第一个位置上,正好符合了最小表示法的性质。对于旋转我们用最小表示法求出最小字典序对于翻转,我们先翻转一下,然后对于翻转的数组用最小表示法求出最小字典序最后对于两种操作取最小的字典序数组。然后给这些数组从小到大排序(方便比较是否相等) 比较相邻数组的字典序是否一样。一样就输出:Twin snowflakes found.不一样输出:No two snowflakes are alike.#include<bits/s..原创 2020-05-15 13:13:56 · 233 阅读 · 0 评论 -
兔子与兔子----------------------------思维(hash)
#include<bits/stdc++.h>using namespace std;const int N=1e6+10;typedef unsigned long long ull;ull P=131;ull h[N],p[N];char s[N];int q,x1,x2,y1,y2;ull get(int l,int r){ return h[r]-h[l-1]*p[r-l+1];}int main(){ scanf("%s",(s+1)); ..原创 2020-05-15 10:51:42 · 183 阅读 · 0 评论 -
双端队列--------------------------------思维(性质)
解析:由题目分析可知,双端队列中一定存在下面性质所以我们要给原数组从小到大排序,判断他们能组成多少个这样的峰谷但是有这么一个问题就是出现重复的数,那么他们下标的排列有可能是峰谷例如:5,1,6或者是5,4,3这样就不好统计峰谷了,最优我们肯定把这些相等的数的下标变成峰谷。所以我们一开始假设我们是下降的,每次找出像等一段的最小下标和最大下标判断当前数是接在后面,继续保持下降(当然题目要求最少的双端队列,要下降的就必须下降)如果不能下降了,那我们就上升。#include<bits/..原创 2020-05-14 13:34:37 · 251 阅读 · 0 评论 -
蚯蚓-------------------------------思维(队列)
解析:性质:蚯蚓i长度>蚯蚓j长度。i蚯蚓切断后的两端长度都大于j蚯蚓切断后的两端长度。因此单调递减根据性质我们用三个队列来模拟优先队列。一个队列存放蚯蚓的长度。一个队列存放切断蚯蚓后左边的长度,一个队列存放切断蚯蚓后右边的长度。因此每次找最长的蚯蚓,我们只要比较着三个队列的队头谁最大即可。用一个额外变量存储每次蚯蚓增加的长度,队列里面保持长度没有增加过#include<bits/stdc++.h>using namespace std;typedef long lo...原创 2020-05-14 11:42:49 · 239 阅读 · 0 评论 -
前缀统计--------------------------------思维(字典树)
解析:字典树对于每一个S串,在结尾处+1T串匹配时,只要一直加即可。就可以确定有多少个前缀了。如果遇到没有创建的节点,直接退出即可#include<bits/stdc++.h>using namespace std;const int N=1e6+100;int s[N][26];char ch[N];int cnt[N],idx;int n,m;void insert(){ int p=0; for(int i=0;ch[i];i++) {..原创 2020-05-14 00:07:15 · 244 阅读 · 0 评论 -
合并果子---------------------优先队列
#include<bits/stdc++.h>using namespace std;int n;priority_queue<int,vector<int>,greater<int> > q;int main(){ cin>>n; for(int i=1,x;i<=n;i++) { cin>>x; q.push(x); } int res=0;..原创 2020-05-13 23:20:38 · 145 阅读 · 0 评论 -
小组队列-------------------------思维(队列)
解析:先开一个数组专门记录编号的开两个队列。一个存储编号为x的队列存的数,一个存储编号(方便得知哪个编号在前)对于插入操作:找出数x的编号pos,把x放到编号为pos的队列中,然后编号pos放到编号队列中对于出队操作:找出编号队列中队头元素为pos ,那么编号为pos的队列出队一个元素。如果编号为pos的队列为空,那么编号队列就要删除该编号(出队)#include<bits/stdc++.h>using namespace std;const int N=1e6+10...原创 2020-05-13 23:11:29 · 299 阅读 · 0 评论 -
火车进栈------------------------思维(dfs+栈)
解析:出站:state1车站:state2进站:state3题目要求需要字典序最小。那么这肯定是state2和state3有关的。state2是个栈存放的是1~k state3是k+1 ~ n那么字典序最小肯定是state2先出栈 假设出栈k如果是state3,那么肯定把k+1,放到state2,再出栈为k+1则先操作state2 为最优#include<bits/stdc++.h>using namespace std;vector<int> stat..原创 2020-05-12 23:27:26 · 316 阅读 · 0 评论 -
直方图中最大的矩形-------------------------思维(单调栈)
解析:用单调栈维护当前方块可以往左右扩展的长度。#include<bits/stdc++.h>using namespace std;const int N=1e5+10000;typedef long long ll;int l[N],r[N],h[N],q[N];int n;int main(){ while(cin>>n,n) { for(int i=1;i<=n;i++) cin>>h[i]; ...原创 2020-05-12 23:21:29 · 251 阅读 · 0 评论 -
编辑器-----------------------------------栈
解析:用两个栈来维护,s数组维护前缀和,f数组维护前缀和最大值I操作:直接将x插入到第一个栈中D操作:直接删除第一个栈的栈顶L操作:光标左移动相当于把前面那个数移动到第二个栈中R操作:光标右移动相当于把后面那个数移动到第一个栈中,同时更新前缀和最大值和前缀和Q操作:直接查询即可#include<bits/stdc++.h>using namespace std;const int N=1e6+10000;int stl[N],str[N],l,r,f[N],s[N];...原创 2020-05-11 19:20:00 · 205 阅读 · 0 评论 -
包含min函数的栈----------------------(单调栈)
解析:维护栈中最小元素:单调栈class MinStack {public: /** initialize your data structure here. */ stack<int> s ,s_min; MinStack() { } void push(int x) { s.push(x); if(s_min.empty()||s_min.top()>=x) s_min.push.原创 2020-05-11 17:31:37 · 148 阅读 · 0 评论 -
任务-------------------------思维(贪心)
解析:给机器和任务都按照x从大到小排序。对于任务i,把满足条件的机器一律放进multiset。然后我们二分找第一个>=任务i的等级。#include<bits/stdc++.h>#define x first#define y secondusing namespace std;const int N=1e6+10;typedef long long ll;typedef pair<int,int> PII;PII mach[N],task[N];in..原创 2020-05-11 16:53:36 · 237 阅读 · 0 评论 -
防线-----------------------------------思维(前缀和+二分+套路题)
解析:1.根据题目所述,最多只有一个位置数量是奇数,那么说明所有位置上的数量之和也一定是奇数。因为奇数+偶数=奇数2.我们通过二分来确定位置。如果[l,mid]的数量总和是奇数那么就缩小范围,反之[mid+1,r]这部分肯定是偶数了。3.数量总和可以用前缀和表示sum[x]:表示第x个位置之前所有位置上数量之和。那么可以O(n)求解出总和。假设s<=x 那么它们之间防具的数量=(min(e,x)-s)/d+1;#include<bits/stdc++.h>using...原创 2020-05-11 15:05:12 · 226 阅读 · 0 评论 -
士兵--------------------------------思维(套路题)
解析:对于y轴 移动到同一水平线 。那么就将y轴坐标排序,求中位数即可、对于x轴,假设有3个数x1,x2,x3 要移动到a,a+1,a+2那么x轴需要移动的次数 |x1-a| +|x2-(a+1)|+|x3-(a+2)|转化一下就是: |(x1)-a|+|(x2-1)-a|+|(x3-2)-a|+…+|(xn-(n-1))-a|处理一下x数组,又转化成求中位数的问题次数=处理y轴次数+处理x轴次数#include<bits/stdc++.h>using namespace ..原创 2020-05-10 00:15:30 · 276 阅读 · 0 评论 -
耍杂技的牛---------------------------思维(贪心)
解析:贪心按照wi+si 从小到大排序即可,然后模拟就行#include<bits/stdc++.h>#define x first#define y secondusing namespace std;const int N=1e5+100;typedef long long ll;typedef pair<ll,ll> PLL;PLL q[N];int n;int main(){ cin>>n; for(int i=1;i<=n;..原创 2020-05-09 23:16:42 · 283 阅读 · 0 评论 -
最大的和---------------------思维
解析:从求最大子段和思想出发。对于二维矩阵我们按照列枚举一段上面有两个蓝颜色的方块,代表着两列。我们把这两列用前缀和表示。就转化成一维的求最大子段和问题了。所以我们只需要枚举即可#include<bits/stdc++.h>using namespace std;const int N=150;int g[N][N];int n;int main(){ cin>>n; for(int i=1;i<=n;i++) for(int j=1;j<..原创 2020-05-09 22:59:28 · 172 阅读 · 0 评论 -
分形-------------------------思维(递归)
解析:递归预处理出1~7级图形。那么对于每一级就输出左上角即可对于x级,就是一个3(x-1) * 3(x-1) 的正方形预处理部分:每一级的预处理都是:由n-1级预处理出来的图形作为第n级的左上角部分,然后依次复制到其他四个地方找出这四个地方的左上角下标#include<bits/stdc++.h>using namespace std;const int...原创 2020-05-08 17:05:29 · 234 阅读 · 0 评论