zoukankan      html  css  js  c++  java
  • 函数库

    快速读入

    int read(){
        int s = 0, f = 0;
        char ch = getchar();
        while(!isdigit(ch))  f |= (ch == '-'), ch = getchar();
        while(isdigit(ch)) s = (s << 1) + (s << 3) + ch - '0' , ch = getchar();
        return f ? -s : s;
    }
    

    自定义输出

    void print(__int128 x){
        if(x > 9) print(x / 10);
        putchar(x % 10 + '0');
    }
    

    (gcd)

    int Get_Gcd(int x, int y) { return y ? Get_Gcd(y, x % y) : x; }
    

    exgcd

    int Exgcd(int a, int b, int &x, int &y) {
        if(b == 0) {
            x = 1, y = 0;
            return a;
        }
        int Gcd = Exgcd(b, a % b, x, y);
        int t = x;
        x = y, y = t - a / b * y;
        return Gcd;
    }
    

    手写队列

    struct sdeque{
        int b[maxn << 1], *a = b + maxn;
        int tail = 0, head = 1;
        sdeque() {}
        bool empty() { return tail + 1 == head;}
        int size() { return tail - head + 1; }
        void push_back(int x) { a[++tail] = x; }
        void push_front(int x) { a[--head] = x; }
        void pop_back() { --tail; }
        void pop_front() { ++head; }
        int back() { return a[tail]; }
        int front() { return a[head]; }
    }q;
    

    高精加&乘(已封装)

    // 压位高精 zhx 亲授
    const int Base = 10000;
    struct Bignum {
        int len, a[MAXN];
        Bignum () { len = 0, memset(a, 0, sizeof a); }
        Bignum operator + (const Bignum &b) {
            Bignum res;
            res.len = max(len, b.len);
            for(int i = 0; i <= res.len; ++i) {
                res.a[i] += a[i] + b.a[i];
                res.a[i + 1] += res.a[i] / Base;
                res.a[i] %= Base;
            }
            if(res.a[res.len + 1]) ++ res.len;
            return res;
        }
        Bignum operator - (const Bignum &b) {
            Bignum res;
            return res;
        }    
        Bignum operator * (const Bignum &b) {
            Bignum res; // a[0] ye you shu de xie fa
            res.len = len + b.len + 1;
            for(int i = 0; i <= len; ++i) {
                for(int j = 0; j <= b.len; ++j) {
                    res.a[i + j] += a[i] * b.a[j];
                    res.a[i + j + 1] += res.a[i + j] / Base;
                    res.a[i + j] %= Base;
                }
            }
            while(res.len && !res.a[res.len]) res.len --;
            return res;
        }
        void Print() {
            printf("%d", a[len]);
            for(int i = len - 1; i >= 0; --i) printf("%04d", a[i]);
            puts("");
        }
        void Input() {
            char s[MAXN];
            cin >> s;
            int now_ = strlen(s);
            len = (now_ - 1) / 4;
            for(int i = 0, j = now_ - 4; i < len; ++i, j -= 4) {
                // fang fa 1
    //            int ans = 0;
    //            for(int k = 0; k < 4; ++k) ans = ans * 10 + s[j + k] - '0';
                // fang fa 2
                sscanf(s + j, "%d", &a[i]);
                s[j] = '';
                // fang fa 3: atoi
            }
            sscanf(s, "%d", &a[len]);
        }
    };
    
    struct Bignum{
        int a[MAXN], len;
        Bignum () { memset(a, 0, sizeof a), len = 0; }
        Bignum operator + (const char s[]) const {
            Bignum t;
            int len2 = strlen(s + 1);
            for(int i = 1; i <= len2; ++i) 
                t.a[i] += a[i] + s[len2 - i + 1] - '0',
                t.a[i + 1] += t.a[i] / 10,
                t.a[i] %= 10;
            for(int i = len2 + 1; i <= len; ++i) t.a[i] = a[i];
            len2 = max(len, len2);
            if(t.a[len2 + 1] != 0) ++ len2;
            t.len = len2;
            return t;
        }
        Bignum operator * (const char s[]) const {
            Bignum t;
            int len2 = strlen(s + 1);
            if(!len) { for(int i = 1; i <= len2; ++i) t.a[i] = s[len2 - i + 1] - '0'; }
            for(int i = 1; i <= len; ++i) 
                for(int j = 1; j <= len2; ++j) 
                    t.a[i + j - 1] += a[i] * (s[len2 - j + 1] - '0'),
                    t.a[i + j] += t.a[i + j - 1] / 10,
                    t.a[i + j - 1] %= 10;
            len2 = len + len2;
            while(!t.a[len2] && len2 > 1) len2--;
            t.len = len2;
            return t;
        }
    };
    

    树剖求LCA(已封装)

    namespace Cut{
        struct edge{
            int to, nxt;
        }e[MAXN << 1];
        int head[MAXN], num_edge = 0;
        void add_edge(int from, int to) { e[++num_edge] = (edge){to, head[from]}, head[from] = num_edge; }
        void dfs(int u, int fa) {
            dep[u] = dep[fa] + 1, fath[u] = fa, siz[u] = 1;
            for(int i = head[u]; i; i = e[i].nxt) {
                int v = e[i].to;
                if(v == fa) continue;
                dfs(v, u);
                siz[u] += siz[v];
                if(siz[v] > siz[son[u]]) son[u] = v;
            }
        }
        void dfs2(int u, int tp) {
            dfn[u] = ++ cnt, pre[cnt] = u, top[u] = tp;
            if(son[u]) dfs2(son[u], tp);
            for(int i = head[u]; i; i = e[i].nxt) {
                int v = e[i].to;
                if(v == fath[u] || v == son[u]) continue;
                dfs2(v, v);
            }
        }
        int Get_Lca(int x, int y) {
            while(top[x] != top[y]) dep[top[x]] < dep[top[y]] ? y = fath[top[y]] : x = fath[top[x]];
            return dep[x] < dep[y] ? x : y;
        }
    }
    

    线性筛素数(欧拉筛)

    int tmp[MAXN], Cnt = 0;
    bool vis[MAXN];
    void Init(int limit) {
        for(int i = 2; i <= limit; ++i) {
            if(!vis[i]) tmp[++ Cnt] = i;
            for(int j = 1; j <= Cnt && i * tmp[j] <= limit; ++j) {
                vis[i * tmp[j]] = true;
                if(i % tmp[j] == 0) break;
            }
        }
    }
    
    namespace LCT {
        #define f fa[now_]
        #define ls son[now_][0]
        #define rs son[now_][1]
        int fa[MAXN], son[MAXN][2];
        LL siz[MAXN];
        bool tag[MAXN];
        void Push_up(int now_) {
            if(!now_) return ;
            siz[now_] = siz[ls] + siz[rs] + 1;
        }
        void Push_Reverse(int now_) {
            if(!now_) return ;
            swap(ls, rs);
            tag[now_] ^= 1;
        }
        void Push_down(int now_) {
            if(tag[now_]) Push_Reverse(ls), Push_Reverse(rs);
            tag[now_] = 0;
        }
        bool IsRoot(int now_) { return son[f][0] != now_ && son[f][1] != now_; }
        bool Whichson(int now_) { return son[f][1] == now_; }
        void Rotate(int now_) {
            int fa_ = f, w = Whichson(now_);
            if(!IsRoot(f)) son[fa[f]][Whichson(f)] = now_;
            fa[now_] = fa[f];
            
            son[fa_][w] = son[now_][w ^ 1];
            fa[son[fa_][w]] = fa_;
            
            son[now_][w ^ 1] = fa_;
            fa[fa_] = now_;
            Push_up(fa_), Push_up(now_);
        }
        void Update(int now_) {
            if(!IsRoot(now_)) Update(f);
            Push_down(now_);
        }
        void Splay(int now_) {
            Update(now_);
            for( ; !IsRoot(now_); Rotate(now_)) {
                if(!IsRoot(f)) Rotate(Whichson(f) == Whichson(now_) ? f : now_);
            }
        }
        void Access(int now_) {
            for(int pre_ = 0; now_; pre_ = now_, now_ = f) {
                Splay(now_), rs = pre_;
                Push_up(now_);
            }
        }
        void MakeRoot(int now_) { Access(now_), Splay(now_), Push_Reverse(now_); }
        int Find(int now_) {
            Access(now_), Splay(now_);
            while(ls) Push_down(now_), now_ = ls;
            Splay(now_);
            return now_;
        }
        void Split(int x_, int y_) { MakeRoot(x_), Access(y_), Splay(y_); } 
        void Link(int x_, int y_) {
            MakeRoot(x_);
            if(Find(y_) != x_) fa[x_] = y_;
        }
        void Cut(int x_, int y_) {
            MakeRoot(x_);
            if(Find(y_) != x_ || fa[y_] != x_ || son[y_][0]) return ;
            fa[y_] = son[x_][1] = 0;
            Push_up(x_);
        }
        int Query(int x_, int y_) {
            Split(x_, y_);
            return siz[y_];
        }
    }
    

    矩阵乘法/快速幂

    struct Matrix {
        int a[MAXN][MAXN];
        Matrix() { memset(a, 0, sizeof a); }
        Matrix operator + (const Matrix &b) const {
            Matrix res;
            for(int i = 1; i <= size; ++i) 
                for(int j = 1; j <= size; ++j) 
                    res.a[i][j] = a[i][j] + b.a[i][j];
            return res;
        }
        Matrix operator - (const Matrix &b) const {
            Matrix res;
            for(int i = 1; i <= size; ++i) 
                for(int j = 1; j <= size; ++j) 
                    res.a[i][j] = a[i][j] - b.a[i][j];
            return res;
        }
        Matrix operator * (const Matrix &b) const {
            Matrix res;
            for(int k = 1; k <= size; ++k) {
                for(int i = 1; i <= size; ++i) {
                    for(int j = 1; j <= size; ++j) {
                        res.a[i][j] += a[i][k] * b.a[k][j];
                    }
                }
            }
            return res;
        } 
        Matrix operator ^ (const LL x) const{
            Matrix res, base;
            for(int i = 1; i <= size; ++i) res.a[i][i] = 1;//初始化res矩阵
            for(int i = 1; i <= size; ++i) 
                for(int j = 1; j <= size; ++j)
                    base.a[i][j] = a[i][j] % mod;
            while(x) {
                if(x & 1) res = res * base;
                base = base * base;
                x >>= 1;
            }
            return res;
        }
    };
    

    网络流-最大流

    bool bfs(){
        memset(dis, -1, sizeof dis);
        queue<int> q;
        q.push(s);
        dis[s] = 0, cur[s] = head[s];
        while(!q.empty()){
            int u = q.front(); q.pop();
            for(int i = head[u]; i; i = e[i].nxt){
                int v = e[i].to;
                if(dis[v] == -1 && e[i].w){
                    q.push(v);
                    cur[v] = head[v]; 
                    dis[v] = dis[u] + 1;
                    if(v == t) return true;
                }
            }
        }
        return false;
    }
    
    int dfs(int u, int limit){//多路增广 
        if(u == t) return limit;
        int flow = 0;
        for(int i = cur[u]; i && flow < limit; i = e[i].nxt){//第二个条件是 流量用要够用 
            cur[u] = i;//当前弧优化,保证每条边只增广一次
            int v = e[i].to;
            if(e[i].w && dis[v] == dis[u] + 1){//如果还有残量并且v点在下一层中 
                int f = dfs(v, min(e[i].w, limit - flow));//向下传递的流量是边限制的流量和剩余的流量去较小值 
                if(!f) dis[v] = -1;//如果没有流量了,标记为-1,表示不能经过了 
                e[i].w -= f;//正边减流量 
                e[i ^ 1].w += f;//反边加流量 
                flow += f;//汇点流量加上获得的流量 
            }
        }
        return flow;
    }
    
    int dinic(){
        int maxflow = 0, flow = 0;
        while(bfs()){
            while(flow = dfs(s, INF)){
                maxflow += flow;
            }
        }
        return maxflow;
    }
    

    网络流-费用流

    bool spfa(){
        bool flag = false;
        memset(dis, 0x3f, sizeof dis);
        memcpy(cur, head, sizeof head);
        deque<int> q;
        q.push_back(s);
        dis[s] = 0, vis[s] = true;
        while(!q.empty()){
            int u = q.front(); q.pop_front();
            vis[u] = false;
            for(int i = head[u]; i; i = e[i].nxt){
                int v = e[i].to;
                if(e[i].w && dis[v] > dis[u] + e[i].cost){
                    dis[v] = dis[u] + e[i].cost;
                    if(!vis[v]) {
                        vis[v] = true;
                        if(!q.empty() && dis[v] < dis[q.front()]) q.push_front(v);
                        else q.push_back(v);
                    }
                    if(v == t) flag = true;
                }
            }
        }
        return flag;
    }
     
    int dfs(int u, int limit){
        if(u == t) return limit;//遇到汇点就返回 
        int flow = 0;
        vis[u] = true;
        for(int i = cur[u]; i && flow < limit; i = e[i].nxt){//指针:可以使cur[u]随i的变化而变化
            cur[u] = i; 
            int v = e[i].to;
            if(!vis[v] && e[i].w && dis[v] == dis[u] + e[i].cost){
                int f = dfs(v, min(e[i].w, limit - flow));
                if(!f) dis[v] = INF;
                res += f * e[i].cost;
                e[i].w -= f;
                e[i ^ 1].w += f;
                flow += f;
    //            if(flow == limit) break;
            }
        }
        vis[u] = false;
        return flow;
    }
     
    int dinic(){
        int maxflow = 0, flow = 0;
        while(spfa()){
            while(flow = dfs(s, INF)){
                maxflow += flow;
            }
        }
        return maxflow;
    }
    
    

    DP 求树的直径

    void dfs(int u, int fa) {
    //    maxm[u] = minn[u] = 0;
        for(int i = head[u]; i; i = e[i].nxt) {
            int v = e[i].to;
            if(v == fa) continue;
            dfs(v, u);
            int t = maxm[v] + 1;
            if(t > maxm[u]) minn[u] = maxm[u], maxm[u] = t;
            else if(t > minn[u]) minn[u] = t;
        }
        ans = max(ans, maxm[u] + minn[u]);
    }
    
  • 相关阅读:
    编写安全检测脚本
    编写监控脚本
    编写一键部署软件脚本
    awk扩展应用
    sed基本用法
    字符串截取及切割,正则表达式,expect预期交互
    For,while,case,shell循环结构
    mybatis使用associaton进行分步查询
    mybatis中封装结果集常见示例
    Mybatis获取数据库自增主键
  • 原文地址:https://www.cnblogs.com/Silymtics/p/14640905.html
Copyright © 2011-2022 走看看