1. 程式人生 > 資訊 >線下店曝光小米 MIX 4 官方渲染圖:搭載未來 CUP 全面屏,藝術品般陶瓷機身,不見 MIX 金標 Logo

線下店曝光小米 MIX 4 官方渲染圖:搭載未來 CUP 全面屏,藝術品般陶瓷機身,不見 MIX 金標 Logo

秦九韶多項式

快速計算\(a_nx^n+a_{n-1}x^{n-1}+\cdots+a_0x^0\)

template<typename T>
T horner(T a[], int n, T x) {
    T res = 0;
    for (int i = n; i >= 0; --i) {
        res = res * x + a[i];
    }
    return res;
}

判斷素數

bool isPrime(int n) {
    if (n == 2 || n == 3) return true;
    if ((n % 6 ^ 1 && n % 6 ^ 5) || n == 1) return false;
    for (int i = 5; i * i <= n; i += 6) {
        if (n % i == 0 || n % (i + 2) == 0) { 
            return false;
        }
    }
    return true;
}

快速冪

不取模

template<typename T>
T fpow(T a, int n) {
	T res = 1;
	while (n) {
		if (n & 1) {
            res = res * a;
        }
		a *= a;
		n >>= 1;
	}
	return res;
}

取模

template<typename T>
T fpow(T a, int n, int p) {
	T res = 1;
	while (n) {
		if (n & 1) {
            res = (res * a) % p;
        }
		a = (a * a) % p;
		n >>= 1;
	}
	return res;
}

逆元

擴充套件歐幾里得

int exgcd(int a, int b, int &x, int &y) {
    if (b == 0) {
        x = 1, y = 0;
        return a;
    }
    int ans = exgcd(b, a % b, y, x);
    y -= a / b * x;
    return ans;
}
int inv(int a, int b) {
    int x, y; 
    exgcd(a, b, x, y);
    return (b + x % b) % b;
}

費馬小定理

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

線性遞推

int inv[MAXN];
void getInvs(int n, int p) {
    inv[1] = 1;
    for(int i = 2; i <= n; ++i) {
        inv[i] = (p - p / i) * inv[p % i] % p;
    }
}

組合數

如果全為\(0\),可以\(\#define ~ int ~ long ~ long\)

呼叫\(C(m, n)\)可以得到\(C_m^n\)的值。

namespace Comb {

const int MAXN = 2e5 + 5;
const int MAXN = 1e9 + 7;
    
template<typename T>
T fpow(T a, int n, int p) {
	T res = 1;
	while (n) {
		if (n & 1) {
            res = (res * a) % p;
        }
		a = (a * a) % p;
		n >>= 1;
	}
	return res;
}
int fact[MAXN], inv[MAXN];
void init() {
    fact[0] = 1;
    for (int i = 1; i < MAXN; ++i) {
		fact[i] = fact[i - 1] * i % MOD;
    }
    inv[MAXN - 1] = fpow(fact[MAXN - 1], MOD - 2, MOD);
    for (int i = MAXN - 2; i >= 0; --i) {
        inv[i] = inv[i + 1] * (i + 1) % MOD;
    }
}
int C(int m, int n) {
    return fact[m] * inv[n] % MOD * inv[m - n] % MOD;
}
    
}; // namespace Comb
using Comb::init, Comb::C;

bool isNotPrime[MAXN]; // 是否是質數
int mu[MAXN], muCnt; // 莫比烏斯函式
int phi[MAXN], phiCnt; // 尤拉函式
int primes[MAXN], primesCnt; // 質數
void seive() {
    phi[1] = mu[1] = 1;
    for (int i = 2; i < MAXN; ++i) {
        if (!isNotPrime[i]) {
            mu[i] = -1;
            phi[i] = i - 1;
            primes[++primesCnt] = i;
        }
        for (int j = 1; j <= primesCnt && i * primes[j] < MAXN; ++j) {
            isNotPrime[i * primes[j]] = true;
            if (i % primes[j] == 0) {
                mu[i * primes[j]] = 0;
                phi[i * primes[j]] = phi[i] * primes[j];
                break;
            }
            else {
                mu[i * primes[j]] = -mu[i];
                phi[i * primes[j]] = phi[i] * (primes[j] - 1);
            }
        }
    }
}

NTT

\(poly\)函式的\(deg\)表示\(a\)\(b\)的項數和,呼叫\(poly\)\(a\)陣列即為相乘後各項係數。

namespace NTT {

const int MAXN = 4e6 + 5;
const int MOD = 998244353;
const int G = 3;

template<typename T>
T fpow(T a, int n) {
	T res = 1;
	while (n) {
		if (n & 1) {
            res = (res * a) % MOD;
        }
		a = (a * a) % MOD;
		n >>= 1;
	}
	return res;
}
int inv(int a) {
    return fpow(a, MOD - 2);
}
struct Complex {
    double x, y;
    Complex(double _x, double _y): x(_x), y(_y) {}
    Complex operator +(Complex oth) {
        return Complex(x + oth.x, y + oth.y);
    }
    Complex operator -(Complex oth) {
        return Complex(x - oth.x, y - oth.y);
    }
    Complex operator *(Complex oth) {
        return Complex(x * oth.x - y * oth.y, x * oth.y + y * oth.x);
    }
};
int R[MAXN], L, limit = 1;
void NTT(int a[], int opt) {
    for (int i = 0; i < limit; ++i) {
        if (i < R[i]) {
            swap(a[i], a[R[i]]);
        }
    }
    for (int mid = 1; mid < limit; mid <<= 1) {
        int val = fpow(G, (MOD - 1) / (mid * 2));
        if (opt == -1) val = inv(val);
        for (int len = mid << 1, pos = 0; pos < limit; pos += len) {
            for (int k = 0, w = 1; k < mid; ++k, w = w * val % MOD) {
                int x = a[pos + k], y = w * a[pos + mid + k] % MOD;
                a[pos + k] = (x + y) % MOD;
                a[pos + k + mid] = (x - y + MOD) % MOD;
            }
        }
    }
    if (opt == 1) return;
    int t = inv(limit);
    for (int i = 0; i < limit; ++i) {
        a[i] = a[i] * t % MOD;
    }
}
void poly(int a[], int b[], int deg) {
    while (limit <= deg) {
        limit <<= 1, ++L;
    }
    for (int i = 0; i < limit; ++i) {
        R[i] = (R[i >> 1] >> 1) | ((i & 1) << (L - 1));
    }
    NTT(a, 1);
    NTT(b, 1);
    for (int i = 0; i < limit; ++i) {
        a[i] = a[i] * b[i] % MOD;
    }
    NTT(a, -1);
}

}; // namespace NTT
using NTT::poly;