模板整理 (施工中 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更新)的主要内容,如果未能解决你的问题,请参考以下文章

常用STL整理 (施工中)

金兄弟钻石地带国际广场模板施工专项方案设计

模板LCA(最近公共祖先)的各种写法(施工中)

模板整理(持续更新)

模板整理(持续更新)

线段树模板整理