int p[N], cnt, num[N]; //num[i]:质数p[i]在Cab中的指数 bool st[N];
voidget_ps(int n) { for (int i = 2; i <= n; i ++ ) { if (!st[i]) p[cnt ++ ] = i; for (int j = 0; p[j] <= n / i; j ++ ) { st[p[j] * i] = true; if (i % p[j] == 0) break; } } }
vector<int> mul(vector<int> A, int b) { vector<int> C; int t = 0; for (int i = 0; i < A.size(); i ++ ) { t += A[i] * b; C.push_back(t % 10); t /= 10; } while (t) { C.push_back(t % 10); t /= 10; } while (C.size() > 1 && C.back() == 0) C.pop_back(); return C; }
//获取n!中的因子p的指数 intget(int a, int b) { int res = 0; while (a) { res += a / b; a /= b; } return res; }
for (int i = 0; i < cnt; i ++ ) num[i] = get(a, p[i]) - get(b, p[i]) - get(a - b, p[i]);
vector<int> res; res.push_back(1); for (int i = 0; i < cnt; i ++ ) while (num[i] -- ) res = mul(res, p[i]); for (int i = res.size() - 1; i >= 0; i -- ) printf("%d", res[i]);
return0; }
exgcd
时间复杂度O(logn)
1 2 3 4 5 6 7 8 9 10 11 12
// 求x, y,使得ax + by = gcd(a, b) intexgcd(int a, int b, int &x, int &y) { if (!b) { x = 1, y = 0; return a; } int gcd = exgcd(b, a % b, y, x); y -= a / b * x; return gcd; }
exgcd求解线性同余方程
n组数据ai,bi,mi,对每组数求出一个xi,满足ai * xi ≡ bi (mod mi),无解输出impossible
LL qmi(LL a, LL k, LL p) { LL res = 1; while (k) { if (k & 1) res = res * a % p; a = a * a % p; k >>= 1; } return res; }
//费马小定理: a ** phi(p) 同余 1 (mod p) 即 a * (a ** (p - 2)) 同余 1 (mod p) intmain() { cin >> n; while (n -- ) { int a, p; scanf("%d%d", &a, &p); if (a % p == 0) puts("impossible"); elseprintf("%lld\n", qmi(a, p - 2, p)); }
return0; }
欧拉函数
用定义求
1 2 3 4 5 6 7 8 9 10 11 12 13
intphi(int x) { int res = x; for (int i = 2; i <= x / i; i ++ ) if (x % i == 0) { res = res / i * (i - 1); while (x % i == 0) x /= i; } if (x > 1) res = res / x * (x - 1);
constint N = 110; constdouble eps = 1e-6; //double与0比较一定要用eps
double a[N][N]; int n;
//返回值 0:无解 1:唯一解 2:无穷多解 intgauss() { int r, c; //枚举每一列 for (r = 1, c = 1; c <= n; c ++ ) { //找当前列绝对值最大的一行 int mx = r; for (int i = r; i <= n; i ++ ) if (fabs(a[i][c]) > fabs(a[mx][c])) mx = i;
//绝对值最大的一行a[mx][c]为0,跳过 if (fabs(a[mx][c]) < eps) continue;
//换到当前的第一行 for (int j = c; j <= n + 1; j ++ ) swap(a[r][j], a[mx][j]);
//a[r][c]化为1 for (int j = n + 1; j >= c; j -- ) a[r][j] /= a[r][c];
//更新后面的行 for (int i = r + 1; i <= n; i ++ ) for (int j = n + 1; j >= c; j -- ) a[i][j] -= a[i][c] * a[r][j];
r ++ ; }
if (r < n + 1) { //第r列开始应该都为 0 = 0 否则无解 for (int i = r; i <= n; i ++ ) if (fabs(a[i][n + 1]) > eps) return0; return2; }
//求出唯一解 for (int i = n; i >= 1; i -- ) for (int j = i + 1; j <= n; j ++ ) a[i][n + 1] -= a[j][n + 1] * a[i][j]; return1; }
intmain() { cin >> n; for (int i = 1; i <= n; i ++ ) for (int j = 1; j <= n + 1; j ++ ) cin >> a[i][j];
int t = gauss(); if (t == 0) puts("No solution"); elseif (t == 1) for (int i = 1; i <= n; i ++ ) printf("%.2lf\n", a[i][n + 1]); elseputs("Infinite group solutions");
intgauss() { int r, c; for (r = 1, c = 1; c <= n; c ++ ) { int mx = r; for (int i = r; i <= n; i ++ ) if (a[i][c]) mx = i;
if (!a[mx][c]) continue;
for (int j = c; j <= n + 1; j ++ ) swap(a[r][j], a[mx][j]);
for (int i = r + 1; i <= n; i ++ ) if (a[i][c]) for (int j = n + 1; j >= c; j -- ) a[i][j] ^= a[r][j];
r ++ ; }
if (r < n + 1) { for (int i = r; i <= n; i ++ ) if (a[i][n + 1]) return0; return2; }
for (int i = n; i >= 1; i -- ) for (int j = i + 1; j <= n; j ++ ) if (a[i][j]) a[i][n + 1] ^= a[j][n + 1]; return1; }
intmain() { cin >> n; for (int i = 1; i <= n; i ++ ) for (int j = 1; j <= n + 1; j ++ ) cin >> a[i][j];
int t = gauss(); if (t == 0) puts("No solution"); elseif (t == 1) for (int i = 1; i <= n; i ++ ) printf("%d\n", a[i][n + 1]); elseputs("Multiple sets of solutions");
return0; }
矩阵快速幂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
//a = b * c typedeflonglong LL;
voidmul(LL a[N][N], LL b[N][N], LL c[N][N]) { LL t[N][N] = {0}; for (int i = 1; i <= n; i ++ ) for (int j = 1; j <= n; j ++ ) for (int k = 1; k <= n; k ++ ) t[i][j] = (t[i][j] + b[i][k] * c[k][j]) % MOD; memcpy(a, t, sizeof t); }
while (k) { if (k & 1) mul(res, res, A); mul(A, A, A); k >>= 1; }