书山有路,学海无涯

模板 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 }

 

posted @ 2017-07-19 19:32  Jimmy_King  阅读(298)  评论(0编辑  收藏  举报