模板 mú bǎn
链式前向星
1 #include<string.h> 2 #define MAX 10000 3 struct node 4 { 5 int to,nex,wei; 6 }edge[MAX*2+5]; 7 int head[MAX+5],cnt; 8 void add(int u,int v,int w)//添加一个单向边u->v 权为w 9 { 10 edge[cnt].to=v; 11 edge[cnt].wei=w; 12 edge[cnt].nex=head[u]; 13 head[u]=cnt++; 14 } 15 int main() 16 { 17 memset(head,-1,sizeof(head));//初始化为-1 18 cnt=0;//初始化 0 19 }
tarjan
1 #include<stack> 2 #include<algorithm> 3 #include<string.h> 4 using namespace std; 5 stack<int>s; 6 int dfn[1000],low[1000],scc[1000];//dfn[]时间戳 low[]最浅到达的点的时间戳 scc[]属于第几个scc 7 int index;//时间戳 8 int sccnum;//强连通的序号&&数量 9 void tarjan(int t) 10 { 11 dfn[t]=low[t]=++index;//记录时间戳 12 s.push(t);//入栈 13 for(int i=head[t];~i;i=edge[i].nex)//遍历儿子 14 { 15 int v=edge[i].to;//v是儿子 16 if(!dfn[v])//如果没走过 17 { 18 tarjan(v);//向下递归 19 low[t]=min(low[t],low[v]);//更新为min(当前,儿子) 20 } 21 else if(!scc[v])//如果不在栈中 22 { 23 low[t]=min(low[t],dfn[v]); 24 } 25 } 26 if(low[t]==dfn[t])//出栈 27 { 28 sccnum++; 29 while(!s.empty()) 30 { 31 int x=s.top(); 32 scc[x]=sccnum; 33 s.pop(); 34 if(x==t)//直到刚刚出去的和现在的一样 35 break; 36 } 37 } 38 } 39 int main() 40 { 41 index=0; 42 sccnum=0; 43 memset(dfn,0,sizeof(dfn)); 44 memset(low,0,sizeof(low)); 45 memset(scc,0,sizeof(scc)); 46 //初始化 47 }
LCA
1 int dep[MAX+5],vis[MAX+5],fa[MAX+5],f[MAX+5][20]; 2 int lca(int x,int y){ 3 if(dep[x]<dep[y]) 4 swap(x,y);//x为较深的 5 for(int i=16;i>=0;i--) 6 if(dep[f[x][i]]>=dep[y]) 7 x=f[x][i]; 8 if(x==y) 9 return x; 10 for(int i=16;i>=0;i--) 11 if(f[x][i]!=f[y][i]) 12 x=f[x][i],y=f[y][i]; 13 return f[x][0]; 14 } 15 void dfs(int t,int d) 16 { 17 dep[t]=d; 18 for(int i=head[t];~i;i=edge[i].nex) 19 { 20 int v=edge[i].to; 21 if(vis[v])continue; 22 vis[v]=1; 23 fa[v]=t; 24 dfs(v,d+1); 25 } 26 } 27 int main() 28 { 29 memset(vis,0,sizeof(vis)); 30 memset(f,0,sizeof(f)); 31 memset(fa,0,sizeof(fa)); 32 }
GCD&LCM
1 //最小公倍数 = a*b / 最大公因数 2 int GCD(int a, int b) 3 { 4 return b == 0 ? a : GCD(b, a%b); 5 } 6 long long int lcm(long long int a, long long int b) 7 { 8 return (a*b / GCD(a, b)); 9 }
快速幂
1 #define MOD 1000000007 2 int ppow(int a, int b)//a^b 3 { 4 int ans = 1, base = a; 5 while (b) 6 { 7 if (b & 1) 8 { 9 ans *= base; 10 ans %= MOD; 11 } 12 base *= base; 13 base %= MOD; 14 b >>= 1; 15 } 16 return ans; 17 }
大数加法
1 string add_string(string s1, string s2) 2 { 3 if (s1 == "" && s2 == "") return "0"; 4 if (s1 == "") return s2; 5 if (s2 == "") return s1; 6 string ans = s1, minn = s2; 7 if (s1.length() < s2.length()) { 8 ans = s2; 9 minn = s1; 10 } 11 int a = ans.length() - 1, b = minn.length() - 1; 12 for (int i = b; i >= 0; --i) { 13 ans[a--] += minn[i] - '0'; // a一直在减 , 额外还要减个'0' 14 } 15 for (int i = ans.length() - 1; i > 0; --i) { 16 if (ans[i] > '9') { 17 ans[i] -= 10;//注意这个是减10 18 ans[i - 1]++; 19 } 20 } 21 if (ans[0] > '9') { 22 ans[0] -= 10; 23 ans = '1' + ans; 24 } 25 return ans; 26 }
大数阶乘
1 typedef long long LL; 2 /* 3 在mult函数中,形参部分:len每次调用函数都会发生改变,n表示每次要乘以的数,最终返回的是结果的长度 4 tip: 阶乘都是先求之前的(n-1)!来求n! 5 初始化Init函数很重要,不要落下 6 */ 7 int mult(int num[], int len, int n) { 8 LL tmp = 0; 9 for (LL i = 0; i < len; ++i) { 10 tmp = tmp + num[i] * n; //从最低位开始,等号左边的tmp表示当前位,右边的tmp表示进位(之前进的位) 11 num[i] = tmp % 10; // 保存在对应的数组位置,即去掉进位后的一位数 12 tmp = tmp / 10; // 取整用于再次循环,与n和下一个位置的乘积相加 13 } 14 while (tmp) { // 之后的进位处理 15 num[len++] = tmp % 10; 16 tmp = tmp / 10; 17 } 18 return len; 19 } 20 int calculating(int n,vector<int>&v) 21 { 22 const int maxn = 100000; 23 int num[maxn], len; 24 //initialize 25 len = 1; 26 num[0] = 1; 27 //--------- 28 for (int i = 2; i <= n; ++i) { 29 len = mult(num, len, i); 30 } 31 for (int i = len - 1; i >= 0; --i) 32 { 33 //printf("%d", num[i]); // 从最高位依次输出,数据比较多采用printf输出 34 v.push_back(num[i]); 35 } 36 return 0; 37 } 38 int main() 39 { 40 int n; 41 cin >> n; 42 vector<int>v; 43 calculating(n,v); 44 //n的阶乘,输出到v 45 }
并查集
1 int sset[100000 + 5]; 2 int find(int a)//x=find(a) 将x放入a的集合 3 { 4 if (sset[a] != a) 5 { 6 sset[a] = find(sset[a]); 7 } 8 return sset[a]; 9 } 10 void merge(int a, int b)//合并a,b 11 { 12 sset[a] = b; 13 }
最长上升子序列(LIS)
1 int b[100000]; 2 int LIS(int a[], int n) { 3 int len = 1; b[0] = a[0]; 4 for (int i = 1; i < n; i++) { 5 b[a[i] > b[len - 1] ? len++ : lower_bound(b, b + len, a[i]) - b] = a[i]; //非降换为>=和upper_bound 6 } 7 return len; 8 }