explain
1. The efficiency of all the following algorithms shows that most of them are measured by themselves or through OJ on the network
2. Some (about 80%) codes come from OJ of other bloggers or networks
3. Update as soon as you think of it
4. It is applicable to xcpc, blue bridge and other algorithm competitions
5. I'm a konjaku, whining, please spray orz
Mathematical algorithm
Maximum common factor gcd
1. STL is ready-made and should be adjusted directly
#include <algorithm> __gcd(a,b);//Both int and long can be used
2. Speed and__ gcd(x,y) is comparable
inline int gcd(int a,int b) {//Bit operation optimization is used, and inline constant level optimization can not be written if(b) while((a%=b) && (b%=a)); return a+b; }
3. The iterative version is a little slower than 1 and 2
inline int gcd(int a,int b){ int tem; while(b){ tem=a; a=b; b=tem%b; } return a; }
4. The most conventional recursive version is slower than 1,2,3
inline int gcd(int a,int b){ if(!b)return a; return gcd(b,a%b); }
Least common multiple
Just remember this formula: (a,b Least common multiple of)*(a,b Maximum common factor of)=a*b;
Single and linear prime numbers
Version 1, fast and easy to RE
bool pri[MAXN];//This should be made into a global variable void prime(int x){ //It can be written as int & X according to the actual situation int i,j; //After all, it takes time for(i=2;i*i<=x;i++){ if(!pri[i]){ for(j=i<<1;j<=x;j+=i) //Pay attention to the data range. If i is too large, it will RE. i < < 1 here is equivalent to i*2 if(!pri[j]) //After testing, it is faster than direct assignment pri[j]=1 pri[j]=1; } } }
Version 2, stable, recommended
bool pri[MAXN];//This should be made into a global variable void prime(int x){ //It can be written as int & X according to the actual situation int i,j,k; //After all, it takes time for(i=2;i*i<=x;i++){ if(!pri[i]){ k=x/i; for(j=2;j<=k;j++) if(!pri[j*i]) //After testing, it is faster than direct assignment pri[i*j]=1 pri[j*i]=1; } } }
Fast power 𞓜 remainder operation
Remainder operation:Although the data is int Range,But it is strongly recommended to open it long long because mo Big will really explode Counting :Take out mod take off,Look at this range, you can consider using it int
inline long long fastpower(long long base,long long power,long long mo){ long long result=1; base%=mo; while(power>0){ if(power & 1){ //This is equivalent to if(power%2==1) result=(result*base)%mo; } base=(base*base)%mo; power>>=1; } return result%mo;//To be on the safe side, I'll take the rest again. I've really stuck with some questions }
search algorithm
DFS
BFS
Dichotomy
Bidirectional BFS
A*
dynamic programming
knapsack problem
I didn't take notes. I'll do it later
01 Backpack
Multiple Backpack
Complete Backpack
Group Backpack
Multi group knapsack
Fully grouped Backpack
Subsequence
LCS
Space complexity of the ultimate optimized version (n) time complexity (m*n)
char a[MAXN]; char b[MAXN]; int len_a,len_b; int tem,pre; int dp[MAXN]; int main(){ scanf("%s",a+1); scanf("%s",b+1); len_a=strlen(a+1); len_b=strlen(b+1); for(int i=1;i<=len_a;i++){ tem=0; for(int j=1;j<=len_b;j++){ pre=tem; tem=dp[j]; if(a[i]==b[j]){ dp[j]=pre+1; }else{ dp[j]=max(dp[j],dp[j-1]); } } } printf("%d",dp[len_b]); return 0; }
LIS
Time complexity of the ultimate version (n*log(n))
int n,a; int dp[100005]; int ans; int main(){ cin>>n; for(int i=0;i<n;i++){ cin>>a; if(a>dp[ans]){ dp[++ans]=a; }else if(a<dp[ans]){ dp[lower_bound(dp+1,dp+ans+1,a)-dp]=a; } } cout<<ans; return 0; }
LCIS
Not yet
Various dp
Not yet, tearful eyes
character string
String matching algorithm
KMP
Time complexity (m+n)
char a[MAXSIZE],b[MAXSIZE]; int next[MAXSIZE]; int n,m; void inita(){//Find the same Prefix suffix table of prefixes next[0]=-1; next[1]=0; int len=0,i=1; while(i<m-1){ if(len==-1 ||b[i]==b[len]){ next[++i]=++len; }else{ len=next[len]; } } } void kmp(){ inita(); int i=0,len=0; while(i<n){ if(len==m-1 && a[i]==b[len]){ len=next[len]; } if(len==-1 || a[i]==b[len]){ len++; i++; }else{ len=next[len]; } } }
Hash retrieval
Theoretical time complexity (m+n),B is a prime number, which is taken at random. The hash algorithm is not 100% accurate, and there is a certain probability of error
(of course, we can also use the simple double method to test again when the hash value is the same, so as to achieve 100% matching accuracy)
In most cases, the speed of hash retrieval is very fast
In fact, you can also write double and triple hashes. The idea is similar. I won't write them here for the time being
The scrolling hash I wrote here has a swish time complexity (m+n)
int B=7;//A prime number void hash_pipei(){ if(m>n) // m is the length of a string and n is the length of b string return; for(int i=0;i<m;i++){ hash_b=hash_b*B+b[i]; t*=B; } for(int i=0;i<m;i++){ hash_a=hash_a*B+a[i]; } if(hash_a==hash_b) printf("YES\n"); for(int i=m;i<n;i++){ hash_a=hash_a*B-t*a[i-m]+a[i]; if(hash_a==hash_b) printf("YES\n"); } }
Query substring hash with time complexity (1)
long long hash_num[MAXN];//All prefix hash values char s[MAXN]; void hash_val(){ int base=7; Bi[0]=1; for(int i=1;i<n;i++){ Bi[i]=Bi[i-1]*base; } hash_num[0]=s[0]; for(int i=1;i<n;i++){ hash_num[i]=hash_num[i-1]*base+s[i]; } } ull hash_LR(int L,int R){//Calculate the hash value of the given interval return hash_num[R]-hash_num[L-1]*Bi[R-L+1]; }
Dictionary tree
Website OI Wiki, this code is really OK. I can borrow it
struct trie { int nex[100000][26], cnt; bool exist[100000]; // Does the string at the end of this node exist void insert(char *s, int l) { // Insert string int p = 0; for (int i = 0; i < l; i++) { int c = s[i] - 'a'; if (!nex[p][c]) nex[p][c] = ++cnt; // If not, add nodes p = nex[p][c]; } exist[p] = 1; } bool find(char *s, int l) { // Find string int p = 0; for (int i = 0; i < l; i++) { int c = s[i] - 'a'; if (!nex[p][c]) return 0; p = nex[p][c]; } return exist[p]; } };
AC automata
Not yet
aggregate
Joint search set
And search the set (non rank optimization) / / note that the first bit I write cannot have 0, because my obsessive-compulsive disorder makes me don't want to initialize
int fa[1005];//global variable inline int find(int &u){ if ( 0==fa[u]) return fa[u]=u; int x=u; while(x!=fa[x]) x=fa[x]; return fa[u]=x; } inline void un(int u,int v){ fa[find(u)]=find(v); } inline bool same_r(int u,int v){ return find(u)==find(v); }
rank optimized version, no notes, I'll fill it up later
graph theory
shortest path
I didn't take notes after learning. Er, I'll learn more when I have time
minimum spanning tree
Kruskal algorithm
#include<bits/stdc++.h> using namespace std; int fa[5005]; inline int find(int &u){ if ( 0==fa[u]) return fa[u]=u; int x=u; while(x!=fa[x]) x=fa[x]; return fa[u]=x; } inline void un(int u,int v){ fa[find(u)]=find(v); } inline bool same_r(int u,int v){ return find(u)==find(v); } struct cpp{ int a,b,c; }edge[200005]; bool cmp(cpp &x,cpp &y){ return x.c<y.c; } int ans; int n,m; int main(){ scanf("%d %d",&n,&m); for(int i=0;i<m;i++) scanf("%d %d %d",&edge[i].a,&edge[i].b,&edge[i].c); sort(edge,edge+m,cmp); for(int i=0;i<m;i++){ if(same_r(edge[i].a,edge[i].b)) continue; un(edge[i].a,edge[i].b); ans+=edge[i].c; } cout<<ans;//Output minimum cost return 0; }
Prim algorithm
It's badly written. Change it when you have time, or borrow it from other bloggers
struct cpp{ int x,cost; }tem; vector<cpp> g[5005]; bool vis[5005]; int num=1; int dis[5005]; int n,m; inline int prim(){ int sum=0,min_cost,cnt=0; while(++cnt<n){ min_cost=2e9; for(unsigned int i=0;i<g[num].size();i++){ dis[g[num][i].x]=min(dis[g[num][i].x],g[num][i].cost); } vis[num]=1; for(int i=1;i<=n;i++){ if(vis[i]==0 && min_cost>dis[i]){ num=i; min_cost=dis[i]; } } sum+=min_cost; } return sum; } int main(){ cin>>n>>m; for(int i=2;i<=n;i++) dis[i]=2e9; for(int i=0,a;i<m;i++){ cin>>a>>tem.x>>tem.cost; g[a].push_back(tem); swap(a,tem.x); g[a].push_back(tem); } cout<<prim(); return 0; }
Priority queue optimization n*log(n) (I wrote it slower, busi)
Don't put it up for the time being
Constant optimization
Read quickly
void read(int& x) {//Here is int or long int f = 1; x = 0; char ch = getchar(); while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();} while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();} x *= f; }