Page Top

常用算法模版

常用算法模版

今天学会在 https://godbolt.org/ 看汇编了。顺便卡了下常数,以及简单的(不是)压行。

编译选项:-std=c++14 -O2 -Wall -Wextra -fno-ms-extensions -fsanitize=address.
万能头文件:bits/stdc++.h.

GOR

循环,默认左闭右开:

  • 前缀 r:反向;
  • 后缀 e:闭区间;
  • 前缀 _:指定步长。
#define gor(_Tp, x, s, t) for (_Tp x = s; x < t; ++x)
#define gore(_Tp, x, s, t) for (_Tp x = s; x <= t; ++x)
#define rgor(_Tp, x, s, t) for (_Tp x = s; x > t; --x)
#define rgore(_Tp, x, s, t) for (_Tp x = s; x >= t; --x)
#define _gor(_Tp, x, s, t, p) for (_Tp x = s; x < t; x += p)
#define _gore(_Tp, x, s, t, p) for (_Tp x = s; x <= t; x += p)
#define _rgor(_Tp, x, s, t, p) for (_Tp x = s; x > t; x -= p)
#define _rgore(_Tp, x, s, t, p) for (_Tp x = s; x >= t; x -= p)

DEGUB

#define debug(x) cerr << #x << " = " << x << endl
#define meow(args...) fprintf(stderr, args)

INT128

  • GCC 4.6 及更高版本:定义 \(\texttt{\_\_int128}\)\(\texttt{unsigned \_\_int128}\) 为内置类型。
  • GCC 4.1 及更高版本:定义 \(\texttt{\_\_int128\_t}\)\(\texttt{\_\_uint128\_t}\)

可以使用 #ifdef _INT128_DEFINED 检测是否支持 \(\texttt{\_\_int128}\)

#ifdef _INT128_DEFINED
    typedef __int128 int128;
    typedef unsigned __int128 uint128;
#else
    typedef __int128_t int128;
    typedef __uint128_t uint128;
#endif
  • \(\texttt{\_\_int128}\) 不支持 cin、cout 等,需要手写输入输出;
  • 不要使用 \(\texttt{\_\_int128}\) 进行模运算,它会非常非常的慢。

快读

#define rr read()
#define ur uread()
#define _rr(x) x = read()
#define _ur(x) x = uread()
signed read() {
    signed num = 0, flag = 1; char ch = getchar();
    for (; !isdigit(ch); ch = getchar()) if (ch == '-') flag = -1;
    for (; isdigit(ch); ch = getchar()) num = num * 10 + ch - '0';
    return num * flag;
} unsigned uread() {
    unsigned num = 0; char ch = getchar();
    while(!isdigit(ch)) ch = getchar();
    while(isdigit(ch)) num = num * 10 + ch - '0', ch = getchar();
    return num;
}

卡常

template<typename _Tp> _Tp _max(const _Tp a, const _Tp b) { return a > b ? a : b; }
template<typename _Tp> _Tp _min(const _Tp a, const _Tp b) { return a < b ? a : b; }
template<typename _Tp> _Tp _abs(const _Tp x) { return x < 0 ? -x : x; }

快速幂

int qpow(int a, int b, int p) {
    int r = 1;
    for (; b; b >>= 1, a = a * a % p) if (b & 1) r = r * a % p;
    return r;
}

欧几里得算法

int gcd(int a, int b) {
    while (b) tie(a, b) = make_tuple(b, a % b);
    return a;
}
int exgcd(int a, int b, int &x, int &y) {
    if (b == 0) { x = 1, y = 0; return a; }
    int d = exgcd(b, a % b, y, x); y -= a / b * x;
    return d;
}

线性同余方程

若保证 \(a \perp m\)(有解),则可以删去第 \(3\) 行。

int lieu1(int a, int b) {
    int x, y, d = exgcd(a, b, x, y);
    if (d != 1) return -1;
    return (x % b + b) % b;
}

若保证 \(\gcd(a, b) \mid n\)(有解),则可以删去第 \(3\) 行。

int lieu(int a, int b, int n) {
    int x, y, d = exgcd(a, b, x, y);
    if (n % d != 0) return -1;
    int t = b / d; return (x % t + t) % t;
}

乘法逆元

若保证 \(a \perp m\)(有解),则可以删去第 \(3\) 行。

int inv(int a, const int m) {
    int x, y, d = exgcd(a, m, x, y);
    if (d != 1) return 0;
    return (x % m + m) % m;
}
int inv(int a, const int m) {
    int x, y;
    exgcd(a, m, x, y);
    return (x % m + m) % m;
}

若保证 \(m \in \mathbb P\)

int inv(int a, const int p) {
    return qpow(a, p - 2, p);
}

求组合数

int comb(int a, int b, const int p) {
    return a < b ? 0 : fr[a] * sv[b] % p * sv[a - b] % p;
}
int lucas(int a, int b, const int p) {
    int r = 1;
    while (a && b) r = r * comb(a % p, b % p, p) % p, a /= p, b /= p;
    return r;
}

欧拉函数

int euler_phi2(int n) {
    int ans = n;
    for (int i = 2; i * i <= n; i++) if (n % i == 0) {
        ans = ans / i * (i - 1);
        while (n % i == 0) n /= i;
    } if (n > 1) ans = ans / n * (n - 1);
    return ans;
}

扩展中国剩余定理合并

void merge(int &a1, int &m1, int a2, int m2) {
    int g = gcd(m1, m2), m = m1 / g * m2;
    int p, q; exgcd(m1 / g, m2 / g, p, q);
    p = p * m1 % m, p = p * ((a2 - a1) / g) % m;
    a1 = (a1 + p + m) % m, m1 = m;
}
posted @ 2023-09-23 13:34  RainPPR  阅读(26)  评论(0编辑  收藏  举报