zoukankan      html  css  js  c++  java
  • 模板集合

    一.基础算法

    贪心

    二分

    整数域上的二分

    分治

    倍增

    搜索

    离散化

    离散化区间

    二.字符串基础

    三.dp(没有固定模板,但以下的主干部分基本相同)

    区间dp

    数位dp

    单调队列优化dp

    四.图论

    拓扑排序

    欧拉回路

    最小生成树(kruskal/prim)

    P3366 【模板】最小生成树

    kruskal

     1 //09/09/19 14:25 kruskal复习 
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <algorithm>
     6 #define ll long long
     7 using namespace std;
     8 
     9 template <typename T> void in(T &x) {
    10     x = 0; T f = 1; char ch = getchar();
    11     while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
    12     while(isdigit(ch)) {x = 10*x+ch-'0'; ch = getchar();}
    13     x *= f;
    14 }
    15 
    16 template <typename T> void out(T x) {
    17     if(x < 0) putchar('-'),x = -x;
    18     if(x > 9) out(x/10);
    19     putchar(x%10+'0');
    20 }
    21 //---------------------------------------------------------------
    22 
    23 const int N = 5005,M = 200005;
    24 
    25 int n,m,s,ans;
    26 int fa[N];
    27 
    28 struct edge {
    29     int u,v,w;
    30     bool operator < (const edge &sed) const {
    31         return w < sed.w;
    32     }
    33 }e[M];
    34 
    35 int find(int x) {
    36     return fa[x] == x ? x : fa[x] = find(fa[x]);
    37 }
    38 
    39 int main() {
    40     int i; in(n); in(m);
    41     for(i = 1;i <= m; ++i) {
    42         in(e[i].u); in(e[i].v); in(e[i].w);
    43     }
    44     sort(e+1,e+m+1);
    45     for(i = 1;i <= n; ++i) fa[i] = i;
    46     int cnt = 0;
    47     for(i = 1;i <= m; ++i) {
    48         int x = find(e[i].u),y = find(e[i].v);
    49         if(x == y) continue;
    50         ++cnt; fa[x] = y; ans += e[i].w;
    51         if(cnt == n-1) break;
    52     }
    53     if(cnt == n-1) out(ans);
    54     else printf("orz");
    55     return 0;
    56 }
    kruskal

    prim

     1 //09/09/19 14:25 kruskal复习 
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <algorithm>
     6 #include <queue>
     7 #define ll long long
     8 using namespace std;
     9 
    10 template <typename T> void in(T &x) {
    11     x = 0; T f = 1; char ch = getchar();
    12     while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
    13     while(isdigit(ch)) {x = 10*x+ch-'0'; ch = getchar();}
    14     x *= f;
    15 }
    16 
    17 template <typename T> void out(T x) {
    18     if(x < 0) putchar('-'),x = -x;
    19     if(x > 9) out(x/10);
    20     putchar(x%10+'0');
    21 }
    22 //---------------------------------------------------------------
    23 
    24 const int N = 5005,M = 200005;
    25 
    26 int n,m,ans;
    27 int dis[N],vis[N];
    28 
    29 struct edge {
    30     int v,w,nxt;
    31     edge(int v = 0,int w = 0,int nxt = 0):v(v),w(w),nxt(nxt){};
    32 }e[M<<1]; int head[N],e_cnt;
    33 
    34 void add(int u,int v,int w) {
    35     e[++e_cnt] = edge(v,w,head[u]); head[u] = e_cnt;
    36 }
    37 
    38 struct node {
    39     int pos,dis;
    40     node(int pos = 0,int dis = 0):pos(pos),dis(dis){};
    41     bool operator < (const node &sed) const {
    42         return dis > sed.dis;//debug 优先队列默认是大根堆
    43     }
    44 };
    45 
    46 priority_queue <node> q;
    47 
    48 void prim() {//贪点 
    49     memset(dis,0x3f,sizeof(dis));
    50     q.push(node(1,0)); dis[1] = 0; int cnt = 0;//debug 此处cnt为已加入树中的点数(不同于kruskal的贪边) 
    51     while(!q.empty()) {
    52         node _u = q.top(); q.pop();
    53         int u = _u.pos;
    54         if(vis[u]) continue; vis[u] = 1;
    55         ++cnt; ans += _u.dis;
    56         if(cnt == n) break;//注意 
    57         for(int i = head[u]; i;i = e[i].nxt) {
    58             int v = e[i].v;
    59             if(dis[v] > e[i].w) {
    60                 dis[v] = e[i].w; q.push(node(v,dis[v]));
    61             }
    62         }
    63     }
    64     if(cnt == n) out(ans);
    65     else printf("orz");
    66 }//prim 的写法与dijkstra如出一辙 主要区别在于dijkstra的dis代表到源点的最短距离,而prim的dis代表未加入树集的点到树集(连通块)的最小距离 
    67 //本质上都是贪心
    68 
    69 int main() {
    70     int i,u,v,w; in(n); in(m);
    71     for(i = 1;i <= m; ++i) {
    72         in(u); in(v); in(w); 
    73         add(u,v,w); add(v,u,w);
    74     }
    75     prim();
    76     return 0;
    77 }
    prim

    最短路(spfa/dijkstra/floyd)

    spfa(slf优化)

    P3371 【模板】单源最短路径(弱化版)

     1 //09/09/19 15:21 spfa(slf优化)复习 
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <algorithm>
     6 #include <queue>
     7 #define ll long long
     8 using namespace std;
     9 
    10 template <typename T> void in(T &x) {
    11     x = 0; T f = 1; char ch = getchar();
    12     while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
    13     while(isdigit(ch)) {x = 10*x+ch-'0'; ch = getchar();}
    14     x *= f;
    15 }
    16 
    17 template <typename T> void out(T x) {
    18     if(x < 0) putchar('-'),x = -x;
    19     if(x > 9) out(x/10);
    20     putchar(x%10+'0');
    21 }
    22 //---------------------------------------------------------------
    23 
    24 const int N = 10007,M = 500007;
    25 
    26 int n,m,s;
    27 
    28 struct edge {
    29     int v,w,nxt;
    30     edge(int v = 0,int w = 0,int nxt = 0):v(v),w(w),nxt(nxt){};
    31 }e[M]; int head[N],e_cnt;
    32 
    33 void add(int u,int v,int w) {
    34     e[++e_cnt] = edge(v,w,head[u]); head[u] = e_cnt;
    35 }
    36 
    37 int dis[N],inque[N];
    38 deque <int> q;
    39 
    40 void spfa() {
    41     memset(dis,0x3f,sizeof(dis));
    42     q.push_back(s); dis[s] = 0; inque[s] = 1;
    43     while(!q.empty()) {
    44         int u = q.front(); q.pop_front(); inque[u] = 0;//易错未写 inque[u] = 0 
    45         for(int i = head[u]; i;i = e[i].nxt) {
    46             int v = e[i].v;
    47             if(dis[v] > dis[u]+e[i].w) {
    48                 dis[v] = dis[u]+e[i].w;
    49                 if(!inque[v]) {
    50                     if(!q.empty() && dis[v] < dis[q.front()]) q.push_front(v);//易错未写 q.empty
    51                     else q.push_back(v);
    52                     inque[v] = 1;
    53                 }
    54             }
    55         }
    56     }
    57     for(int i = 1;i <= n; ++i) {
    58         if(dis[i] != 0x3f3f3f3f) out(dis[i]);
    59         else out((1<<31)-1);
    60         putchar(' ');
    61     }
    62 }
    63 
    64 int main() {
    65     int i,u,v,w; in(n); in(m); in(s);
    66     for(i = 1; i <= m; ++i) {
    67         in(u); in(v); in(w); add(u,v,w);
    68     }
    69     spfa();
    70     return 0;
    71 }
    spfa(slf优化)

    dijkstra(堆优化)

    P4779 【模板】单源最短路径(标准版)

     1 //09/09/19 15:39 dijkstra(堆优化)复习 
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <algorithm>
     6 #include <queue>
     7 #define ll long long
     8 using namespace std;
     9 
    10 template <typename T> void in(T &x) {
    11     x = 0; T f = 1; char ch = getchar();
    12     while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
    13     while(isdigit(ch)) {x = 10*x+ch-'0'; ch = getchar();}
    14     x *= f;
    15 }
    16 
    17 template <typename T> void out(T x) {
    18     if(x < 0) putchar('-'),x = -x;
    19     if(x > 9) out(x/10);
    20     putchar(x%10+'0');
    21 }
    22 //---------------------------------------------------------------
    23 
    24 const int N = 100007,M = 200007;
    25 
    26 int n,m,s;
    27 
    28 struct edge {
    29     int v,w,nxt;
    30     edge(int v = 0,int w = 0,int nxt = 0):v(v),w(w),nxt(nxt){};
    31 }e[M]; int head[N],e_cnt;
    32 
    33 void add(int u,int v,int w) {
    34     e[++e_cnt] = edge(v,w,head[u]); head[u] = e_cnt;
    35 }
    36 
    37 ll dis[N];
    38 bool vis[N];
    39 
    40 struct node {
    41     int pos; ll dis;
    42     node(int pos = 0,ll dis = 0):pos(pos),dis(dis){};
    43     bool operator < (const node &sed) const {
    44         return dis > sed.dis;//debug 又写反了 
    45     }
    46 };
    47 
    48 priority_queue <node> q;
    49 
    50 void dijkstra() {
    51     memset(dis,0x7f,sizeof(dis));
    52     q.push(node(s,0)); dis[s] = 0; //vis[s] = 1;
    53     while(!q.empty()) {
    54         node _u = q.top(); q.pop();
    55         int u = _u.pos;
    56         if(vis[u]) continue; vis[u] = 1;
    57         for(int i = head[u]; i;i = e[i].nxt) {
    58             int v = e[i].v; 
    59             if(dis[v] > dis[u]+e[i].w) {
    60                 dis[v] = dis[u]+e[i].w;
    61                 //if(vis[v]) continue;
    62                 q.push(node(v,dis[v]));
    63                 //vis[v] = 1;
    64             }
    65         }
    66     }
    67     for(int i = 1;i <= n; ++i) out(dis[i]),putchar(' ');
    68 }
    69 
    70 int main() {
    71     int i,u,v,w; in(n); in(m); in(s);
    72     for(i = 1; i <= m; ++i) {
    73         in(u); in(v); in(w); add(u,v,w);
    74     }
    75     dijkstra();
    76     return 0;
    77 }
    dijkstra(堆优化)

    *有向图中,单汇最短可以通过建反图的方式转化为单源最短(P1629,P1342)

    floyd

    多源最短路

    传递闭包

    求最小环(输出方案)

    差分约束系统

    (强连通分量)缩点

    割点/桥

    点/边双连通分量

    二分图

    二分图最大匹配

    二分图完美匹配

    二分图带权匹配

    *网络流

    最大流

    最小费用流

    五.数据结构(数据处理)

    前缀和

    RMQ

    差分/二维差分

    树状数组

    线段树

    平衡树(splay)

    六.树

    树的前/中/后序遍历

    树的直径

    树的重心

    lca(倍增求lca/树链剖分求lca)

    树上差分(边差分/点差分)

    树链剖分

      1 //09/09/19 08:55 树剖复习 
      2 #include <iostream>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <algorithm>
      6 #define ll long long
      7 using namespace std;
      8 
      9 template <typename T> void in(T &x) {
     10     x = 0; T f = 1; char ch = getchar();
     11     while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
     12     while(isdigit(ch)) {x = 10*x+ch-'0'; ch = getchar();}
     13     x *= f;
     14 }
     15 
     16 template <typename T> void out(T x) {
     17     if(x < 0) putchar('-'),x = -x;
     18     if(x > 9) out(x/10);
     19     putchar(x%10+'0');
     20 }
     21 //---------------------------------------------------------------
     22 
     23 const int N = 1e5+7;
     24 
     25 int n,m,r,p,a[N]; 
     26 
     27 struct edge {
     28     int v,nxt;
     29     edge(int v = 0,int nxt = 0):v(v),nxt(nxt){};
     30 }e[N<<1]; int head[N],e_cnt;
     31 
     32 void add(int u,int v) {
     33     e[++e_cnt] = edge(v,head[u]); head[u] = e_cnt;
     34 }
     35 //---------------------------------------------------------------
     36 //init
     37 //pre_dfs1
     38 int fa[N],dep[N],sz[N],son[N];
     39 void dfs1(int u) {
     40     dep[u] = dep[fa[u]]+1; sz[u] = 1; int maxs = 0;
     41     for(int i = head[u]; i;i = e[i].nxt) {
     42         int v = e[i].v; if(v == fa[u]) continue; 
     43         fa[v] = u; dfs1(v); sz[u] += sz[v];//debug not wt sz[u] += sz[v]
     44         if(sz[v] > maxs) maxs = sz[v],son[u] = v;
     45     }
     46 }
     47 //pre_dfs2
     48 int top[N],id[N],w[N],cnt;
     49 void dfs2(int u,int ctop) {
     50     top[u] = ctop; id[u] = ++cnt; w[id[u]] = a[u];
     51     if(son[u]) dfs2(son[u],ctop);
     52     for(int i = head[u]; i;i = e[i].nxt) {
     53         int v = e[i].v; if(v == fa[u] || v == son[u]) continue; dfs2(v,v);
     54     }
     55 }
     56 //---------------------------------------------------------------
     57 //segment tree
     58 ll sum[N<<2],lazy[N<<2];
     59 
     60 void P_dn(int u,int l,int r) {
     61     if(!lazy[u]) return;
     62     int mid = (l+r)>>1;
     63     sum[u<<1] = (sum[u<<1]+(lazy[u]*(mid-l+1))%p)%p; lazy[u<<1] = (lazy[u<<1]+lazy[u])%p;
     64     sum[u<<1|1] = (sum[u<<1|1]+(lazy[u]*(r-mid))%p)%p; lazy[u<<1|1] = (lazy[u<<1|1]+lazy[u])%p;
     65     lazy[u] = 0;
     66 }
     67 
     68 void Build(int u,int l,int r) {
     69     if(l == r) {sum[u] = w[l]; return;}
     70     int mid = (l+r)>>1;
     71     Build(u<<1,l,mid); Build(u<<1|1,mid+1,r);
     72     sum[u] = (sum[u<<1]+sum[u<<1|1])%p;
     73 }
     74 
     75 void A(int u,int l,int r,int x,int y,ll k) {
     76     if(x <= l && y >= r) {sum[u] = (sum[u]+(k*(r-l+1))%p)%p; lazy[u] = (lazy[u]+k)%p; return;}
     77     P_dn(u,l,r); int mid = (l+r)>>1;
     78     if(x <= mid) A(u<<1,l,mid,x,y,k); if(y > mid) A(u<<1|1,mid+1,r,x,y,k);
     79     sum[u] = (sum[u<<1]+sum[u<<1|1])%p;
     80 }
     81 
     82 ll Q(int u,int l,int r,int x,int y) {
     83     if(x <= l && y >= r) return sum[u];
     84     P_dn(u,l,r); int mid = (l+r)>>1; ll res = 0;//debug 线段树基础不扎实,返回值应用long long 
     85     if(x <= mid) res = (res+Q(u<<1,l,mid,x,y))%p; if(y > mid) res = (res+Q(u<<1|1,mid+1,r,x,y))%p;//debug 第二个忘记%p 30pts -> 100pts 
     86     return res;
     87 }
     88 //---------------------------------------------------------------
     89 //chain
     90 
     91 void modify(int x,int y,int z) {
     92     while(top[x] != top[y]) {//不在一条重链上 
     93         if(dep[top[x]] < dep[top[y]]) swap(x,y);//每次让深的跳 
     94         //A(1,1,n,top[x],x,z); x = top[x];//WA
     95         A(1,1,n,id[top[x]],id[x],z); 
     96         x = fa[top[x]];//易错1不加id //易错2 不写 x = fa[top[x]] //易错3不加fa 
     97     }
     98     if(dep[x] < dep[y]) swap(x,y);
     99     A(1,1,n,id[y],id[x],z);
    100 }
    101 
    102 ll query(int x,int y) {
    103     ll res = 0;
    104     while(top[x] != top[y]) {
    105         if(dep[top[x]] < dep[top[y]]) swap(x,y);
    106         res = (res+Q(1,1,n,id[top[x]],id[x]))%p; 
    107         x = fa[top[x]];
    108     }
    109     if(dep[x] < dep[y]) swap(x,y);
    110     return res = (res+Q(1,1,n,id[y],id[x]))%p;
    111 }
    112 
    113 
    114 int main() {
    115 //    freopen("0.in","r",stdin);
    116     int i,x,y,z,op; in(n); in(m); in(r); in(p);
    117     for(i = 1;i <= n; ++i) in(a[i]);
    118     for(i = 1;i < n; ++i) {
    119         in(x); in(y); add(x,y); add(y,x);
    120     }
    121     dfs1(r); dfs2(r,r); Build(1,1,n);
    122     while(m--) {
    123         in(op); in(x);
    124         if(op == 1) {
    125             in(y); in(z); modify(x,y,z%p);
    126         }//1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z
    127         else if(op == 2) {
    128             in(y); out(query(x,y)),putchar('
    ');
    129         }//2 x y 表示求树从x到y结点最短路径上所有节点的值之和
    130         else if(op == 3) {
    131             in(z); A(1,1,n,id[x],id[x]+sz[x]-1,z%p);
    132         }//3 x z 表示将以x为根节点的子树内所有节点值都加上z
    133         else {
    134             out(Q(1,1,n,id[x],id[x]+sz[x]-1)); putchar('
    ');
    135         }//4 x 表示求以x为根节点的子树内所有节点值之和
    136     }
    137     return 0;
    138 }
    树剖模板 

    *点分治

    七.数学基础

    gcd/lcm 

    线性筛

    快速幂

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <cmath>
     6 #include <queue>
     7 #include <vector>
     8 #define ll long long
     9 using namespace std;
    10 
    11 template <typename T> void in(T &x) {
    12     x = 0; T f = 1; char ch = getchar();
    13     while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
    14     while(isdigit(ch)) {x = 10*x+ch-'0'; ch = getchar();}
    15     x *= f;
    16 }
    17 
    18 template <typename T> void out(T x) {
    19     if(x < 0) putchar('-'),x = -x;
    20     if(x > 9) out(x/10);
    21     putchar(x%10+'0');
    22 }
    23 //---------------------------------------------------------------
    24 
    25 ll b,p,k;
    26 
    27 ll power(ll a,ll b,ll p) {
    28     ll res = 1%p;//debug 1^0 mod 1 = 0//注意%p
    29     for(;b;b >>= 1) {
    30         if(b&1) res = (res*a)%p;
    31         a = (a*a)%p;
    32     }
    33     return res;
    34 }
    35 
    36 int main() {
    37     in(b); in(p); in(k);
    38     printf("%lld^%lld mod %lld=%lld",b,p,k,power(b,p,k));
    39     return 0;
    40 }
    快速幂

    八.STL

    九.骗分

    随机化

    random_shuffle

    模拟退火

  • 相关阅读:
    面试知识点连接汇总:
    spring学习二:jdbc相关回顾以及spring下dao
    spring学习一:spring入门及相关概念介绍
    日常暖手
    日常暖手
    从破解实例到探讨反调试
    一个有趣的CM
    复健小CM
    Windows下利用py2exe生成静默运行的命令行程序
    获取指定窗口内的文本
  • 原文地址:https://www.cnblogs.com/mzg1805/p/11489649.html
Copyright © 2011-2022 走看看