模板整理 (施工中 2017.8.21更新)
Posted Hyouka
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板整理 (施工中 2017.8.21更新)相关的知识,希望对你有一定的参考价值。
目录
数据结构
1 字典树
图论
1 网络流dinic
2 zkw费用流
3 无向图的强联通分量
数论
1 中国剩余定理
2 大质数判定
3 约瑟夫环
其他
1 祖传头文件
2 大数
数据结构
1.字典树
使用时记得先初始化第一个点
const int MAXN = 1e2 + 5; int Maxlen, Maxnum; int T, K; struct node { int next[27]; int v, num; void init() { v=-1; num = 0; memset(next,-1,sizeof(next)); } }; struct node L[1000000]; int tot=0; void add(char a[]) { int now=0; int len = strlen(a); for(int i=0; i<len; i++) { int tmp=a[i]-‘a‘; int next=L[now].next[tmp]; if(next==-1) { next=++tot; L[next].init(); L[now].next[tmp]=next; } now=next; L[now].num ++; if(L[now].num >= 3) { if(Maxlen < i + 1) { Maxlen = i + 1; Maxnum = L[now].num; } else if(Maxnum < L[now].num && Maxlen <= i + 1) { Maxnum = L[now].num; } } } L[now].v=0; } int query(char s2[]) { int len = strlen(s2); int now = 0; for(int i = 0; i < len; i++) { int temp = s2[i] - ‘a‘; int next = L[now].next[temp]; if(next == -1) return 0; now = next; } return L[now].num; } int main() { L[0].init(); return 0; }
图论
1.网络流Dinic
const int maxn = 405; //开四倍 const int maxe = 4*maxn*maxn; const int inf = 0x3f3f3f3f; struct MaxFlow { struct Edge { int v, w, nxt; } edge[maxe]; int head[maxn], tot, level[maxn]; void init(){ memset(head,-1,sizeof(head)); tot=0; } void add(int u, int v, int w) { edge[tot].v = v; edge[tot].w = w; edge[tot].nxt = head[u]; head[u] = tot++; edge[tot].v = u; edge[tot].w = 0; edge[tot].nxt = head[v]; head[v] = tot++; } bool bfs(int s, int t) { memset(level, -1, sizeof(level)); queue<int>q; q.push(s); level[s] = 0; while(!q.empty()) { int u = q.front(); q.pop(); for(int i = head[u]; ~i; i = edge[i].nxt) { if(edge[i].w > 0 && level[edge[i].v] < 0) { level[edge[i].v] = level[u] + 1; q.push(edge[i].v); } } } return level[t] > 0; } int dfs(int u, int t, int f) { if(u == t) return f; for(int i = head[u]; ~i; i = edge[i].nxt) { int v = edge[i].v; if(edge[i].w > 0 && level[v] > level[u]) { int d = dfs(v, t, min(f, edge[i].w)); if(d > 0) { edge[i].w -= d; edge[i ^ 1].w += d; return d; } } } level[u] = -1; //不太确定,如果WA了把这句删掉试试 return 0; } int solve(int s, int t) { int flow = 0, f; while(bfs(s, t)) { while(f = dfs(s, t, inf)) flow += f; } return flow; } }F;
2.
zkw费用流
const int MX = 80000; const int MXE = 4 * MX * MX; const int ME = 4e5 + 5;//边的数量 struct MCMF { int S, T;//源点,汇点 int tot, n; int st, en, maxflow, mincost; bool vis[MX]; int head[MX], cur[MX], dis[MX]; int roade[MX], roadv[MX], rsz; //用于打印路径 queue <int> Q; struct Edge { int v, cap, cost, nxt, flow; Edge() {} Edge(int a, int b, int c, int d) { v = a, cap = b, cost = c, nxt = d, flow = 0; } } E[ME], SE[ME]; void init(int _n) { n = _n, tot = 0; for(int i = 0; i <= n; i++) head[i] = -1; } void edge_add(int u, int v, int cap, int cost) { E[tot] = Edge(v, cap, cost, head[u]); head[u] = tot++; E[tot] = Edge(u, 0, -cost, head[v]); head[v] = tot++; } bool adjust() { int v, min = INF; for(int i = 0; i <= n; i++) { if(!vis[i]) continue; for(int j = head[i]; ~j; j = E[j].nxt) { v = E[j].v; if(E[j].cap - E[j].flow) { if(!vis[v] && dis[v] - dis[i] + E[j].cost < min) { min = dis[v] - dis[i] + E[j].cost; } } } } if(min == INF) return false; for(int i = 0; i <= n; i++) { if(vis[i]) { cur[i] = head[i]; vis[i] = false; dis[i] += min; } } return true; } int augment(int i, int flow) { if(i == en) { mincost += dis[st] * flow; maxflow += flow; return flow; } vis[i] = true; for(int j = cur[i]; j != -1; j = E[j].nxt) { int v = E[j].v; if(E[j].cap == E[j].flow) continue; if(vis[v] || dis[v] + E[j].cost != dis[i]) continue; int delta = augment(v, std::min(flow, E[j].cap - E[j].flow)); if(delta) { E[j].flow += delta; E[j ^ 1].flow -= delta; cur[i] = j; return delta; } } return 0; } void spfa() { int u, v; for(int i = 0; i <= n; i++) { vis[i] = false; dis[i] = INF; } Q.push(st); dis[st] = 0; vis[st] = true; while(!Q.empty()) { u = Q.front(), Q.pop(); vis[u] = false; for(int i = head[u]; ~i; i = E[i].nxt) { v = E[i].v; if(E[i].cap == E[i].flow || dis[v] <= dis[u] + E[i].cost) continue; dis[v] = dis[u] + E[i].cost; if(!vis[v]) { vis[v] = true; Q.push(v); } } } for(int i = 0; i <= n; i++) { dis[i] = dis[en] - dis[i]; } } int zkw(int s, int t) { st = s, en = t; spfa(); mincost = maxflow = 0; for(int i = 0; i <= n; i++) { vis[i] = false; cur[i] = head[i]; } do { while(augment(st, INF)) { memset(vis, false, n * sizeof(bool)); } } while(adjust()); return mincost; } } M;
3.无向图的强联通分量
const int MX = 1e5 + 10; struct Edge { int u, v, nxt; } E[MX]; int Head[MX], erear; void edge_init() { erear = 0; memset(Head, -1, sizeof(Head)); } void edge_add(int u, int v) { E[erear].u = u; E[erear].v = v; E[erear].nxt = Head[u]; Head[u] = erear++; } int n, m, IN[MX], cnt[MX], val[MX]; int bsz, ssz, dsz; int Low[MX], DFN[MX]; void Init_tarjan(int n) { bsz = ssz = dsz = 0; for(int i = 1; i <= n; ++i) Low[i] = DFN[i] = 0; } int Stack[MX], inStack[MX], Belong[MX]; void trajan(int u, int e) { inStack[u] = 1; Stack[++ssz] = u; DFN[u] = Low[u] = ++dsz; for(int i = Head[u]; ~i; i = E[i].nxt) { int v = E[i].v; if((i ^ 1) == e) continue; if(!DFN[v]) { trajan(v, i); Low[u] = min(Low[u], Low[v]); } else if(inStack[v]) { Low[u] = min(Low[u], Low[v]); } } if(DFN[u] == Low[u]) { bsz++; int v; do { v = Stack[ssz--]; inStack[v] = 0; Belong[v] = bsz; } while(ssz && v != u); } } void tarjan_solve(int n) { dsz = bsz = ssz = 0; memset(DFN, 0, sizeof(DFN)); for(int i = 1; i <= n; i++) { if(!DFN[i]) trajan(i, -1); } /*缩点*/ edge_init(); for(int i = 0; i < 2 * m; i += 2) { int u = E[i].u, v = E[i].v; u = Belong[u]; v = Belong[v]; if(u == v) continue; edge_add(u, v); edge_add(v, u); } }
数论
1.中国剩余定理
LL gcd(LL a, LL b, LL &x, LL &y) { if(b == 0) { x =1, y = 0; return a; } LL r = gcd(b, a % b, x, y); LL t = y; y = x - a / b * y; x = t; return r; } LL multi(LL a, LL b, LL mod) { LL ret = 0; while(b) { if(b & 1) { ret = ret + a; if(ret >= mod) ret -= mod; } a = a + a; if(a >= mod) a -= mod; b >>= 1; } return ret; } LL crt(int n, LL m[], LL a[]) { LL M = 1, d, y, x = 0; for(int i = 0; i < n; i++) M *= m[i]; for(int i = 0; i < n; i++) { LL w = M / m[i]; d = gcd(m[i], w, d, y); y = (y % m[i] + m[i]) % m[i]; x = ((x + multi(multi(a[i], w, M), y, M)) % M + M) % M; } return x; }
2.大质数判定
LL multi(LL a, LL b, LL mod) { LL ret = 0; while(b) { if(b & 1) ret = ret + a; if(ret >= mod) ret -= mod; a = a + a; if(a >= mod) a -= mod; b >>= 1; } return ret; } LL power(LL a, LL b, LL mod) { LL ret = 1; while(b) { if(b & 1) ret = multi(ret, a, mod); a = multi(a, a, mod); b >>= 1; } return ret; } bool Miller_Rabin(LL n) { LL u = n - 1, pre, x; int i, j, k = 0; if(n == 2 || n == 3 || n == 5 || n == 7 || n == 11) return true; if(n == 1 || (!(n % 2)) || (!(n % 3)) || (!(n % 5)) || (!(n % 7)) || (!(n % 11))) return false; for(; !(u & 1); k++, u >>= 1); for(i = 0; i < 5; i++) { x = rand() % (n - 2) + 2; x = power(x, u, n); pre = x; for(j = 0; j < k; j++) { x = multi(x, x, n); if(x == 1 && pre != 1 && pre != (n - 1)) return false; pre = x; } if(x != 1) return false; } return true; }
3.约瑟夫环
/* F[n] = (F[n - 1] + m) % n, F[1] = 0 返回的下标从0 开始,复杂度大约为O(m) */ int Joseph(int n, int m) { if(n == 1) return 0; if(m == 1) return n - 1; LL pre = 0; int now = 2; while(now <= n) { if(pre + m >= now) { pre = (pre + m) % now; now++; } else { int a = now - 1 - pre, b = m - 1; int k = a / b + (a % b != 0); if(now + k > n + 1) k = n + 1 - now; pre = (pre + (LL)m * k) % (now + k - 1); now += k; } } return pre; }
其他
1.祖传头文件
#include <iostream> #include <cstring> #include <stdio.h> #include <algorithm> #include <queue> #include <vector> #include <iomanip> #include <math.h> #include <map> using namespace std; #define FIN freopen("input.txt","r",stdin); #define FOUT freopen("output.txt","w",stdout); #define INF 0x3f3f3f3f #define INFLL 0x3f3f3f3f3f3f3f #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 typedef long long LL; typedef pair<int, int> PII;
2.大数
const int MX = 2500; const int MAXN = 9999; const int DLEN = 4; /*已重载>+- % 和print*/ class Big { public: int a[MX], len; Big(const int b = 0) { int c, d = b; len = 0; memset(a, 0, sizeof(a)); while(d > MAXN) { c = d - (d / (MAXN + 1)) * (MAXN + 1); d = d / (MAXN + 1); a[len++] = c; } a[len++] = d; } Big(const char *s) { int t, k, index, L, i; memset(a, 0, sizeof(a)); L = strlen(s); len = L / DLEN; if(L % DLEN) len++; index = 0; for(i = L - 1; i >= 0; i -= DLEN) { t = 0; k = i - DLEN + 1; if(k < 0) k = 0; for(int j = k; j <= i; j++) { t = t * 10 + s[j] - ‘0‘; } a[index++] = t; } } Big operator/(const int &b)const { Big ret; int i, down = 0; for(int i = len - 1; i >= 0; i--) { ret.a[i] = (a[i] + down * (MAXN + 1)) / b; down = a[i] + down * (MAXN + 1) - ret.a[i] * b; } ret.len = len; while(ret.a[ret.len - 1] == 0 && ret.len > 1) ret.len--; return ret; } bool operator>(const Big &T)const { int ln; if(len > T.len) return true; else if(len == T.len) { ln = len - 1; while(a[ln] == T.a[ln] && ln >= 0) ln--; if(ln >= 0 && a[ln] > T.a[ln]) return true; else return false; } else return false; } Big operator+(const Big &T)const { Big t(*this); int i, big; big = T.len > len ? T.len : len; for(i = 0; i < big; i++) { t.a[i] += T.a[i]; if(t.a[i] > MAXN) { t.a[i + 1]++; t.a[i] -= MAXN + 1; } } if(t.a[big] != 0) t.len = big + 1; else t.len = big; return t; } Big operator-(const Big &T)const { int i, j, big; bool flag; Big t1, t2; if(*this > T) { t1 = *this; t2 = T; flag = 0; } else { t1 = T; t2 = *this; flag = 1; } big = t1.len; for(i = 0; i < big; i++) { if(t1.a[i] < t2.a[i]) { j = i + 1; while(t1.a[j] == 0) j++; t1.a[j--]--; while(j > i) t1.a[j--] += MAXN; t1.a[i] += MAXN + 1 - t2.a[i]; } else t1.a[i] -= t2.a[i]; } t1.len = big; while(t1.a[t1.len - 1] == 0 && t1.len > 1) { t1.len--; big--; } if(flag) t1.a[big - 1] = 0 - t1.a[big - 1]; return t1; } int operator%(const int &b)const { int i, d = 0; for(int i = len - 1; i >= 0; i--) { d = ((d * (MAXN + 1)) % b + a[i]) % b; } return d; } Big operator*(const Big &T) const { Big ret; int i, j, up, temp, temp1; for(i = 0; i < len; i++) { up = 0; for(j = 0; j < T.len; j++) { temp = a[i] * T.a[j] + ret.a[i + j] + up; if(temp > MAXN) { temp1 = temp - temp / (MAXN + 1) * (MAXN + 1); up = temp / (MAXN + 1); ret.a[i + j] = temp1; } else { up = 0; ret.a[i + j] = temp; } } if(up != 0) { ret.a[i + j] = up; } } ret.len = i + j; while(ret.a[ret.len - 1] == 0 && ret.len > 1) ret.len--; return ret; } void print() { printf("%d", a[len - 1]); for(int i = len - 2; i >= 0; i--) printf("%04d", a[i]); } };
以上是关于模板整理 (施工中 2017.8.21更新)的主要内容,如果未能解决你的问题,请参考以下文章