線下店曝光小米 MIX 4 官方渲染圖:搭載未來 CUP 全面屏,藝術品般陶瓷機身,不見 MIX 金標 Logo
阿新 • • 發佈:2021-08-09
秦九韶多項式
快速計算\(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;