• noip 数学整理


    // 质数判定
    (1) 暴力
    bool check(int x) {
        for (int i = 2; i * i <= x; ++i) if (x % i == 0) return 0;
        return 1;
    }
    (2)miller_rabin
    bool check(LL a) {
    	for (int i = 0; i < 12; ++i) {
    		if(f[i] >= a) break;
    		if(Qpow(f[i], a - 1, a) != 1) return 0;
    		LL pp = a - 1;
    		while(pp % 2 == 0) {
    			pp /= 2; LL y = Qpow(f[i], pp, a);
    			if(Qmul(y, y, a) == 1 && y != 1 && y != a - 1) return 0;
    		}
    	} return 1;
    }
    
    //n的所有约数
    vector <int> a;
    for (int i = 2; i * i <= n; ++i) {
        if (n % i == 0) {
            a.push_back(i);
            if (i * i != n) a.push_back(n / i);
        }
    }
    
    //分解质因数
    vector <int> p, c;
    for (int i = 2; i * i <= n; ++i) {
        if (n % i == 0) {
            p.push_back(i);
            int cnt = 0;
            while (n % i == 0) ++ cnt, n /= i;
            c.push_back(cnt);
        }
    }
    if (n > 1) p.push_back(n), c.push_back(1);
    
    //线性筛
    (1)筛质数
    for (int i = 2; i <= lim; ++i) {
        if (!vis[i]) pri[++ cnt] = i;
        for (int j = 1; j <= cnt && i * pri[j] <= lim; ++j) {
            vis[i * pri[j]] = 1;
            if (i % pri[j] == 0) break;
        }
    }
    
    (2)筛欧拉函数
    phi[1] = 1;
    for (int i = 2; i <= lim; ++i) {
        if (!vis[i]) pri[++ cnt] = i, phi[i] = i - 1;
        for (int j = 1; j <= cnt && i * pri[j] <= lim; ++j) {
            vis[i * pri[j]] = 1;
            if (i % pri[j] == 0) {
                phi[i * pri[j]] = phi[i] * pri[j]; break;
            }
            phi[i * pri[j]] = phi[i] * phi[pri[j]];
        }
    }
    
    (3) 筛约束约数个数
    记t[i]为i的约数个数,e[i]为i的最小素因子的个数
    因为是线性筛,每个数只被它最小的质因子筛到,所以
    a pri[j]是i*pri[j]的最小质因子
    b 如果i是pri[j]的倍数,pri[j]也是i的最小质因子
    <1> i是素数,t[i] = 2, e[i] = 1
    <2> i是pri[j]的倍数
        t[i * pri[j]] = t[i] / (e[i] + 1) * (e[i] + 2)
        e[i] = e[i] + 1
    <3> i不是pri[j]的倍数
        t[i * pri[j]] = t[i] * t[pri[j]]
        e[i * pri[j]] = 1
    
    for (int i = 2; i <= lim; ++i) {
        if (!vis[i]) pri[++ cnt] = i, t[i] = 2, e[i] = 1;
        for (int j = 1; j <= cnt && i * pri[j] <= lim; ++j) {
            vis[i * pri[j]] = 1;
            if (i % pri[j] == 0) {
                e[i * pri[j]] = e[i] + 1;
                t[i * pri[j]] = t[i] / (e[i] + 1) * (e[i] + 2); break;
            }
            e[i * pri[j]] = 1;
            t[i * pri[j]] = t[i] * t[pri[j]];
        }
    }
    
    (4)筛约数和
    记t[i]为i的约数和,e[i]为i的最小素因子的那一项等比数列
    t[i] = (1 + p1 + p1^2 + ...)(1 + p2 + p2^2 + ....) ...(1 + pn + pn^2 + ...)
    e[i] = (1 + p1 + p1^2 + ...)
    因为是线性筛,每个数只被它最小的质因子筛到,所以
    a pri[j]是i*pri[j]的最小质因子
    b 如果i是pri[j]的倍数,pri[j]也是i的最小质因子
    <1> i是素数,t[i] = i + 1, e[i] = i + 1
    <2> i是pri[j]的倍数 
        t[i * pri[j]] = t[i] / e[i] * (e[i] * pri[j] + 1)
        e[i * pri[j]] = e[i] * pri[j] + 1
    <3> i不是pri[j]的倍数
        t[i * pri[j]] = t[i] * (pri[j] + 1)
        e[i * pri[j]] = pri[j] + 1
    
    for (int i = 2; i <= lim; ++i) {
        if(!vis[i]) pri[++ cnt] = i, e[i] = t[i] = i + 1;
        for (int j = 1; j <= cnt && i * pri[j] <= lim; ++j) {
            vis[i * pri[j]] = 1;
            if (i % pri[j] == 0) {
                t[i * pri[j]] = t[i] / e[i] * (e[i] * pri[j] + 1);
                e[i * pri[j]] = e[i] * pri[j] + 1;
            } 
            t[i * pri[j]] = t[i] * (pri[j] + 1);
            e[i * pri[j]] = pri[j] + 1;
        }
    }
    
    //ECGCD
    void Exgcd(int a, int b, int &x, int &y) {
        if (b == 0) {x = 1; y = 0; return;}
        Exgcd(b, a % b, y, x);
        y -= a / b * x;
    }
    方程 ax + by = c有解, 当且仅当 gcd(a, b) | c
    d = gcd(a, b)
    a /= d, b /= d, c /= d
    通解: x = x * c + k * b, y = y * c - k * a 
    最小正整数解 x *= c, x = (x % b + b) % b
    
    //线性同余方程
    求解 ax=b(mod m)
    转化为:ax + my = b
    
    tips:求解 ax + by = c时
    若 a < 0, 则 a = -a, c = -c
    
    //线性同余方程组
    x = b1 (mod a1)
    x = b2 (mod a2)
    
    b1 + a1 * x1 = b2 + a2 * x2
    a1 * x1 + a2 * x2 = b2 - b1
    解出最小的正整数解x'
    得到新方程 x = (a1 * x' +b1) (mod lcm(a1, b2))
    
    LL excrt() {
    	LL M = a[1], B = b[1], x, y;
    	for (int i = 2; i <= n; ++i) {
    		LL C = b[i] - B;
    		LL d = gcd(M, a[i]);
    		if (C % d) return -1;
    		exgcd(M, a[i], x, y);
    		x = Mul(x, C / d, a[i] / d);
    		B += x * M;
    		M = M / d * a[i];
    		B = (B % M + M) % M;
    	}
    	return B;
    }
    
    //欧拉函数
    phi[i]表示1...i中与i互质数的个数
    i = p1 ^ a1 * p2 ^ a2 *...pn ^ a
    phi[i] = sum{i / pj * (pj - 1)}
    
    //欧拉定理
    当gcd(a, n) = 1时, a ^ phi[n] = 1 (mod n)
    推论
    <1> 若gcd(a, n) = 1, 则a ^ b = a ^ (b % phi[n]) (mod n)
    <2> 若b > phi[n], 则a ^ b = a ^ (b % phi[n] + phi[n]) (mod n)
    
    //费马小定理
    <1> p是质数,gcd(a, p) = 1, 则a ^ (p - 1) = 1 (mod p)
    <2> p是质数,对于任意a, a ^ p = a (mod p)
    
    //乘法逆元
    a * x = 1 (mod m)
    x 为 a 在mod m意义下的逆元
    求法 
    <1> m 为质数 pow(a, m - 2) 为逆元
    <2> ax + bm = 1, exgcd求解即可
    <3> 递推 inv[1] = 1, inv[i] = (p - p / i) * inv[p % i]
    
    //组合数 C(n, m) = n! / (m! * (n - m)!)
    递推 :
    c[0][0] = 1;
    for (int i = 1; i <= n; ++i) {
    	c[i][0] = c[i][i] = 1;
    	for (int j = 1; j <= i - 1; ++j) 
    	c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
    }
    
    //二项式定理
    (a + b) ^ n = sum {C(n, i) * a ^ i * b ^ (n - i)} (0 <= i <= n)
    
    //卡特兰数
    P(n) = C(2n, n) - C(2n, n - 1) = 1 / (n + 1) * C(2n, n)
    前几项:(n从0开始)
    1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786
    递推:
    P0 = 1
    <1> Pn = sum {Pi * Pn - i + 1} (0 <= i <= n - 1)
    <2> Pn+1 = 2 * (2n + 1) / (n + 2) * Pn
    奇卡特兰数满足 n = 2 ^ k - 1
    https://quincyqiang.cn/2017/08/24/06-%E5%8D%A1%E7%89%B9%E5%85%B0%E6%95%B0/
    http://blog.miskcoo.com/2015/07/catalan-number
    

      

    选择了oi,只便风雨兼程罢!!!!!
  • 相关阅读:
    每日一题(文化课)一题---------19/7/30
    XXXXX,这个域名
    CF1037E. Trips
    bzoj3124: [Sdoi2013]直径 树形dp two points
    luogu P3952 时间复杂度 模拟
    AGC016D
    CF444E. DZY Loves Planting
    模拟赛
    HDU 3949 XOR [线性基|高斯消元]
    博客搬家
  • 原文地址:https://www.cnblogs.com/oi-forever/p/9905718.html
Copyright © 2020-2023  润新知