// // // // // // // // // // // // // //

数学基础 2

数学基础

前言

又回来整理 前面学的都忘干净了...

大多数(或者是全部)定理只有结论 不涉及证明 代码如果可以的话后面会补充


由于不分篇目的原因 内容势必会非常杂乱 但是应该不会分开写了 反正也没人看


前面其实已经有数学基础1了 这是 2 写的原因是上一遍和没学差不多

所以有些东西是重复的

或许后面还会有 3 或者 4 什么的 也有可能继续在这个后面写


3 写不动了 受限于个人水平 有些东西学不会 理解能力跟不上了 所以开4了(雾


平衡三进制

对称三进制 不标准的计数体系 数字由 -1, 0, 1 构成 基数为 3 用 z 代替 -1

0    0
1    1
2    1Z
3    10
4    11
5    1ZZ

-1   Z
-2   Z1
-3   Z0
-4   ZZ
-5   Z11

负数即为将正数的数字倒转 负数最高位为 z 正数最高位为 1

转换

先将一个数表示为 3 进制 从最低位开始迭代 跳过任何的 0 和 1 遇到 2 时将其变为 z 下一位的数字加 1 遇到 3 变为 0 下一位数字加 1

平衡三进制具有唯一性

一些符号

\([x]\) 表示 \(x\) 下取整

\(p_k\) 表示第 \(k\) 个素数

\(\pi(x)\) 表示 \(1-\)x 范围内的素数个数

\(\mu(x)\) 表示莫比乌斯函数

\(\#S\) 表示 \(S\) 集合的大小

\(\delta(x)\) 表示 \(x\) 的最小质因子

\(P^+(n)\) 表示 \(x\) 的最大质因子

虽然并没有什么用就是了

素数

定义

如果一个数 除了 \(1\) 和它本身外 无其他因子 这个数被称为质数 否则称为合数

\[\pi(x) \approx \frac{x}{\ln x} \]

\(1\) 既不是素数也不是合数

质因数分解

定义 任何一个大于 \(1\) 的正整数都能被唯一分解为有限个质数的乘积 写作:

\[N = p_1^{c_1}p_2^{c_2}...p_m^{c_m} \]

  • 唯一分解定理

    对于某一正整数 \(n\) 其质因数分解的方式是唯一的

  • 正整数除法
    将 被除数 与 除数 先进行质因数分解 再将对应每个素数的指数相减

\[\begin{array} & & 24 \div 8\\ = & (2 ^ 3 \times 3 ^ 1) \div 2^3\\ = & 2^{3 - 3} \times 3^{1 - 0}\\ = & 3 \end{array} \]

有

若 \(m \mid n\)

则 \(n \div m = p_1^{a_1 - b_1} p_2^{a_2 - b_2}...p_m^{a_m - b_m}\)

满足 \(a_1 \geq b_1, a_2 \geq b_2 , ...\)

验证 \(n\) 是否可以被 \(m\) 整除 比较两数质因数分解后的各项质数

素数判定

试除法

不断尝试小于 \(x\) 且大于 \(1\) 的自然数 只要有一个能整除 \(x\) 则 \(x\) 为合数 否则 \(x\) 是素数

由于约数都是成对存在的 所以只需尝试 \([1, \sqrt x]\) 即可

筛法求素数

埃氏筛

复杂度 \(O(n\log ^2n)\)

对于枚举的数 枚举其倍数 并且将其倍数标记为合数

一个数会被其所有因子筛一遍 造成时间上的浪费 至于优化

欧拉筛(线筛)

复杂度 \(O(n)\)

思路与埃筛基本相同 但是保证了每个数只被其最小质因子筛一遍 对于枚举的数 \(i\) 如果其之前没有被标记 将其即为质数 然后枚举其质数倍 将其倍数标记为合数 在 \(i \mod 第j个素数 = 0\) 时 结束枚举

费马小定理

如果 \(p\) 为质数 有整数 \(a\) 且 \(a \bot p\) 则 \(a^{p - 1} \equiv 1 \mod p\)

与欧拉定理的关系

当 \(p\) 为质数时

\[\varphi(p) = p - 1 \]

此时的欧拉定理可写为

\[a^{\varphi(p)} \equiv 1 \mod p\\ a_{p - 1} \equiv 1 \mod p \]

即 费马小定理

费马小定理即欧拉定理中 \(p\) 为质数时的特殊情况

二次探测定理

若 \(p\) 为质数 且 \(x^2 \equiv 1 \mod p\)

那么 \(x \equiv 1 \mod p\) 和 \(x \equiv p - 1\mod p\) 中的一个成立

\(p \mid (x + 1)(x - 1)\)


约数

定义

如果 \(a \mid b\) 则 \(a\) 为 \(b\) 的约数 \(b\) 为 \(a\) 的倍数

特别地 任何数都是 \(0\) 的约数

一般地 有 \(1 \mid a\) 与 \(a \mid a\) 则 \(1\), \(a\) 称 \(a\) 的平凡因子

约数的几种求法

  • 试除法

    枚举 \([1, \sqrt n]\) 中所有整数 进行试除 判断 \(n\) 能否整除

  • 优化

    当求 \([1, n]\) 中所有数的约数时 上面的试除法复杂度就变成了 \(O(n \sqrt n)\)

    \(1\) 到 \(n\) 中一一个数 \(x\) 为约数的数 \(x, 2x, 3x, ..., \lfloor \frac nx \rfloor \times x\) 枚举到 \(x\) 的时候 枚举 \(x\) 的倍数 使他们的约数加上一个 \(x\)

    复杂度 \(O(n\log n)\)

对任意数 \(n\) 求约数个数

根据 \(n = p_1^{c_1}p_2^{c_2}...p_m^{c_m}\)

通项公式: \(num = \sum_{i = 1}^m(c_i + 1)\)

对任意数 \(n\) 求约数和

通项公式: \(sum = \prod_{i = 1}^m\sum_{j = 0}^{c_i}p_i^j\)


最大公约数 与 最小公倍数

最大公约数

定义 : 有 \(n\), \(m\) 两整数 \(n, m\) 的最大公约数 \(d\) 满足 \(d \mid n\) 且 \(d \mid m\) 的最大的 \(d\) 记作 \(d = \gcd(n, m)\) 简写为 \((n, m)\)

设 \(n = p_1^{a_1}p_2^{a_2}...p_k^{a_k}, m = p_1^{b_1}p_2^{b_2}...p_k^{b_k}\)

则 \(d = p_1^{\min \{a_1, b_1 \}}p_2^{\min \{a_2, b_2 \}}...p_k^{\min \{a_k, b_k \}}\)

最小公倍数

定义 : 有 \(n\), \(m\) 两整数 \(n, m\) 的最小公倍数 \(l\) 满足 \(n \mid l\) 且 \(m \mid l\) 的最小的 \(l\) 记作 \(l = lcm(n, m)\) 简写为 \([n, m]\)

\(l = d = p_1^{\max \{a_1, b_1 \}}p_2^{\max \{a_2, b_2 \}}...p_k^{\max \{a_k, b_k \}}\)

另 有 \((n, m) \times [n, m] = nm\)


互质

定义 : 若 \(\gcd(a, b) = 1\) 称 \(a, b\) 互质 记为 \(a \bot b\)

即: 当 \(a, b\) 进行质因数分解之后 没有相等的质因数

性质 :

  • 对于两个不同的质数 \(m, n\) 有 \(\gcd(n, m) = 1\)
  • 对于任意相邻的整数 \(n, m\) 有 \(\gcd(n, m) = 1\)
  • 对任意自然数 \(n\) 有 \(\gcd(n, 1) = 1\)
  • 一个质数 \(m\) 和一个合数 \(n\) 若 \(m \nmid n\) 则 \(\gcd(n, m) = 1\)

欧拉函数

定义 : 对正整数 \(n\) 满足 \(a \bot n\) \(a < n\) 的 \(a\) 的个数 即为 \(n\) 的欧拉函数的值 记作 \(\varphi(n)\)

性质:

  1. \(\varphi(1) = 1\)
  2. \(\varphi(p) = p - 1\)
  3. 若 \(n \bot m\) 则 \(\varphi(nm) = \varphi(n)\varphi(m)\)
  4. 当 \(n\) 为奇数 \(\varphi(2n) = \varphi(n)\)
  5. \(\varphi(p^a) = p^a(1 - \frac 1p)\)
  6. 对任意大于 \(1\) 的正整数 \(n\) 有\(\varphi(n) = n\prod_{i = 1}^n(1 - \frac 1{p_i})\)

对 5 :

比 \(p^a\) 小的数有 \(p^a - 1\) 个 与 \(p^a\) 不互质的数 一定是 \(p\) 的倍数 \(p\) 的倍数可以表示为 \(tp, t \in [1, p_{a - 1} - 1]\)

与 \(p\) 互质的数的个数:

\(\varphi(p^a) \\ = (p^a - 1) - (p^{a - 1} - 1) \\ = p^a - p^{a - 1} \\ = p^{a - 1}(p - 1) \\ = p^a(1 - \frac 1p)\)

对 6 :

设 \(n = p_1^{c_1}p_2^{c_2}...p_k^{c_k}\)

\(\varphi(n) \\ = \varphi(p_1^{c_1}p_2^{c_2}...p_k^{c_k}) \\ = \varphi(p_1^{c_1})\varphi(p_2^{c_2})...\varphi(p_k^{c_k}) \\ = p_1^{c_1}(1 - \frac 1{p_1})p_2^{c_2}(1 - \frac 1{p_2})...p_k^{c_k}(1 - \frac 1{p_k}) \\ = (p_1^{c_1}p_2^{c_2}...p_k^{c_k}) \times (1 - \frac 1{p_1})(1 - \frac 1{p_2})...(1 - \frac 1{p_k}) \\ = n\prod_{i - 1}^n(1 - \frac 1{p_i})\)

欧拉函数筛(咕)

众所周知 有个叫欧拉函数筛的东西 还有欧拉线筛 可以在筛质数的时候顺便筛一下欧拉函数 这里先咕着 后面补

记着这个在 1 里面是有的

欧拉定理

对于两个互质的数 \(a, p\) 有 \(a^{\varphi(p)} \equiv 1 \mod p\)


关于同余的一些概念

  1. 反身性: \(a \equiv a \mod m\)
  2. 对称性: 若 \(a \equiv b \mod m\) 则 \(b \equiv a \mod m\)
  3. 传递性: 若 \(a \equiv b \mod m\) 且 \(b \equiv c \mod m\) 则 \(a \equiv c \mod m\)
  4. 若 \(a \equiv b \mod m, c \equiv d \mod m\) 则 \(a \pm c \equiv b \pm d \mod m\)
  5. 若 \(a \equiv b \mod m, c \equiv d \mod m\) 则 \(ac \equiv bd \mod m\)
  6. 若 \(a \equiv b \mod m, n \in N\) 则 \(a^n \equiv b^n \mod m\)
  7. 若 \(ac \equiv bd \mod m\) 则 \(a \equiv b \mod \frac m{(c, m)}\) 当 \((c, m) = 1\) 时 \(a \equiv b \mod m\)
  8. 若 \(a \equiv b \mod m_i, i = 1, 2, ..., k\) 则 \(a \equiv b \mod [m_1, m_2, ..., m_k]\)

欧几里得与扩展欧几里得

欧几里得定理

\(\gcd(a, b) = \gcd(b, a \% b)\) 当 \(b = 0\) 时 有 \(\gcd(a, b) = |a|\)

应用: 可以方便的求 \((a, b)\)

int gcd(int a, int b) {return b ? gcd(b, a % b) : a;}

裴蜀定理

设 \(a, b\) 为不全为 \(0\) 的整数 则存在 \(x, y\) 使 \(ax + by = \gcd(a, b)\)

特别的 当 \(\gcd(a, b) = 1\) 则 存在 \(x, y\) 使 \(ax + by = 1\)

题目: 裴蜀定理

大概是定理的推广形式

代码

/*
  Time: 6.19
  Worker: Blank_space
  Source: P4549 【模板】裴蜀定理
*/
/*--------------------------------------------*/
#include<cstdio>
#define Abs(x) ((x) < 0 ? -(x) : (x))
/*--------------------------------------头文件*/
int n, ans;
/*------------------------------------变量定义*/
inline int read() {
	int x = 0, f = 1; char ch = getchar();
	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
	return x * f;
}
/*----------------------------------------快读*/
int gcd(int _a, int _b) {return _b ? gcd(_b, _a % _b) : _a;}
/*----------------------------------------函数*/
int main() {
	n = read(); ans = read(); ans = Abs(ans);
	for(int i = 2, x; i <= n; i++) x = read(), ans = gcd(ans, Abs(x));
	printf("%d", ans);
	return 0;
}

扩展欧几里得

对于不完全为 \(0\) 的两个数 \(a, b\) 必然存在无数个 \(x, y\) 使方程 \(ax + by = \gcd(a, b)\) 成立

求特殊解:

void exgcd(int a, int b, int &d, int &x, int &y) {
    if(b) exgcd(b, a % b, d, y, x), y -= x * (a / b);
    else d = a, x = 1, y = 0;
}

应用:

  1. 求解不定方程
  2. 求解同余方程
  3. 求解模的逆元
  4. 求解同余方程组

对 1:

对方程 \(ax + by = c\)

不定方程 \(ax + by = \gcd(a, b)\) 有无数组解

若 \(\gcd(a, b) \nmid c\) 则原方程无解

若 \(\gcd(a, b) \mid c\) 设 \(d = \gcd(a, b)\)

原方程可转化为 \(a(x \times \frac dc) + b(y\times \frac dc) = c\times \frac dc\)

令 \(x_1 = x \times \frac dc, y_1 = y \times \frac dc\) 得

\(ax_1 + by_1 = d\) 求解该方程得 \(x_1, y_1\)

得: \(x = x_1 \times \frac cd, y = y_1 \times \frac cd\)

既得原方程的解

对 2:

\(ax \equiv c \mod b \to ax + nb = c + mb\)

有 \(ax + (n - m)b = c\) 求解该不定方程所得 \(x\) 即为原方程的解

但是这不一定是最小正整数解

x = (x + b) % b;

题目: 同余方程

代码

/*
  Time: 6.19
  Worker: Blank_space
  Source: P1082 [NOIP2012 提高组] 同余方程
*/
/*--------------------------------------------*/
#include<cstdio>
#define int long long
/*--------------------------------------头文件*/
inline void File() {
	freopen(".in", "r", stdin);
	freopen(".out", "w", stdout);
}
/*----------------------------------------文件*/
int a, b, d, x, y;
/*------------------------------------变量定义*/
inline int read() {
	int x = 0, f = 1; char ch = getchar();
	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
	return x * f;
}
/*----------------------------------------快读*/
void exgcd(int _a, int _b, int &_d, int &_x, int &_y) {
	if(_b) exgcd(_b, _a % _b, _d, _y, _x), _y -= _x * (_a / _b);
	else _d = _a, _x = 1, _y = 0;
}
/*----------------------------------------函数*/
signed main() {
	a = read(); b = read(); exgcd(a, b, d, x, y); x /= d; printf("%lld", (x % b + b) % b);
	return 0;
}

对 3:

适用于模数不为质数的情况

即解: \(x \times inv(x) \equiv 1 \mod p\)

令 \(a = x, x = inv(x)\) 有 \(ax \equiv 1 \mod p\)

对 4:

解如下方程组:

\(\begin{cases}x \equiv a_1 \mod b_1 \\ x \equiv a_2 \mod b_2 \\ ... \\ x \equiv a_n \mod b_n \end{cases}\)

其中 \(a, b\) 为非负整数 不保证模数互质

求解:

使用 \(exgcd\) 对同余方程进行合并

假设当前已经求出了前 \(k - 1\) 个方程的解 \(x_{k - 1}\) 设 \(M = lcm_{i = 1}^{k - 1}b_i\)

即前 \(k - 1\) 个方程的通解为 \(x_{k - 1} + tM\) 现在目标是使第 \(k\) 个方程的解为前 \(k - 1\) 个方程的通解的同时也满足第 \(k\) 个方程的条件 设 \(x_k = x_{k - 1} + tM\) 有 \(x_{k - 1} + tM \equiv a_k \mod b_k\) 显然 该方程是可解的 得 \(t\) 的值 则可求 \(x_k = x_{k - 1} + tM\) 经过 \(n\) 次操作后 即得原方程组的解

代码:(数据较大 龟速乘)

/*
  Time: 6.19
  Worker: Blank_space
  Source: P4777 【模板】扩展中国剩余定理(EXCRT)
*/
/*--------------------------------------------*/
#include<cstdio>
#define int long long
/*--------------------------------------头文件*/
inline void File() {
	freopen(".in", "r", stdin);
	freopen(".out", "w", stdout);
}
/*----------------------------------------文件*/
int n, M, ans, d, x, y;
/*------------------------------------变量定义*/
inline int read() {
	int x = 0, f = 1; char ch = getchar();
	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
	return x * f;
}
/*----------------------------------------快读*/
int mul(int _a, int _b, int mod, int res = 0) {for(; _b; _a = (_a + _a) % mod, _b >>= 1) if(_b & 1) res = (res + _a) % mod; return res;}
void exgcd(int _a, int _b, int &_d, int &_x, int &_y) {
	if(_b) exgcd(_b, _a % _b, _d, _y, _x), _y -= _x * (_a / _b);
	else _d = _a, _x = 1, _y = 0;
}
/*----------------------------------------函数*/
signed main() {
	n = read(); M = read(); ans = read();
	for(int i = 2; i <= n; i++)
	{
		int b = read(), a = read(); a = ((a - ans) % b + b) % b;
		exgcd(M, b, d, x, y); if(a % d) {puts("-1"); return 0;}
		x = mul(x, a / d, b); ans += x * M; M = M / d * b; ans = (ans % M + M) % M;
	}
	printf("%lld", ans);
	return 0;
}


乘法逆元

对于在模意义下的除法 对模数 \(p\) 和除数 \(x\) 往往可以找到一个特殊的数 \(y\) 用 $ \times y$ 代替 \(\div x\) 将 \(y\) 记作 \(x\) 的逆元 记作 \(inv(x)\)

通过定义: \(x \times inv(x) \equiv 1 \mod p\)

求解逆元

这里本来有四种方法 但是由于太懒 所以变成了三种

  1. 费马小定理

    只适用于模数为质数的情况 这是最常用的一种 因为大多数题目的模数都会设为质数(不是刻意卡的话)

    费马小定理: \(x^{p - 1} \equiv 1 \mod p\)

    故有: \(x^{p - 1} \equiv x \times inv(x) \mod p\)

    两侧同除 \(x\) 有: \(inv(x) \equiv x^{p - 2} \mod p\)

    所以快速幂直接求 \((x^{p - 2}) \% p\) 即为 \(\div x\) 模 \(p\) 意义下的逆元

  2. 递推

    只适用于模数为质数的情况 如果要求的逆元数量很多而且连续 就可以使用递推

    \(inv(i) = -\lfloor \frac pi \rfloor \times inv(p \% i) \% p\)

    正确性:

    设 \(p = ik + r\)

    有 \(p \equiv 0 \mod p\)

    故 \(ik + r \equiv 0 \mod p\)

    两边同乘 \(inv(i)inv(r)\)

    有 \(i \times inv(i) \times k \times inv(r) + r \times inv(r) \times inv(i) \equiv 0 \mod p\) 化简 得 \(k \times inv(r) + inv(i) \equiv 0 \mod p\)

    故 \(inv(i) \equiv -k \times inv(r) \mod p\)

    即 \(inv(i) \equiv -\lfloor \frac pi \rfloor \times inv(p \% i) \mod p\)

    但是是求最小正整数解 加个 \(p\) 调一下

    即 \(inv(i) = (p - \lfloor \frac pi \rfloor) \times inv(p \% i) \% p\)

  3. 扩展欧几里得

    模数可以不为质数

    由逆元的定义 \(x \times inv(x) \equiv 1 \mod p\)

    把这个东西当做同余方程来解就好了

题目: 乘法逆元

这个题目适合用线性求逆元

代码

/*
  Time: 6.19
  Worker: Blank_space
  Source: P3811 【模板】乘法逆元
*/
/*--------------------------------------------*/
#include<cstdio>
#define int long long 
/*--------------------------------------头文件*/
const int C = 1e6 + 7;
/*------------------------------------常量定义*/
inline void File() {
	freopen(".in", "r", stdin);
	freopen(".out", "w", stdout);
}
/*----------------------------------------文件*/
int n, p, inv[C << 2];
/*------------------------------------变量定义*/
inline int read() {
	int x = 0, f = 1; char ch = getchar();
	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
	return x * f;
}
/*----------------------------------------快读*/

/*----------------------------------------函数*/
signed main() {
	n = read(); p = read(); inv[1] = 1;
	for(int i = 2; i <= n; i++) inv[i] = (p - p / i) * inv[p % i] % p;
	for(int i = 1; i <= n; i++) printf("%lld\n", inv[i]);
	return 0;
}

题目: 有理数取余

看一眼 高精!?

高个鬼 要模数干啥的

费马小定理的写法

代码

/*
  Time: 6.19
  Worker: Blank_space
  Source: P2613 【模板】有理数取余
*/
/*--------------------------------------------*/
#include<cstdio>
#define int long long
/*--------------------------------------头文件*/
const int mod = 19260817;
/*------------------------------------常量定义*/
int a, b;
/*------------------------------------变量定义*/
inline int read() {
	int x = 0, f = 1; char ch = getchar();
	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9') {x = ((x << 3) + (x << 1) + (ch ^ 48)) % mod; ch = getchar();}
	return x * f;
}
/*----------------------------------------快读*/
int power(int _a, int _b, int res = 1) {for(; _b; _a = _a * _a % mod, _b >>= 1) if(_b & 1) res = res * _a % mod; return res;}
/*----------------------------------------函数*/
signed main() {
	a = read(); b = read(); printf("%lld", a * power(b, mod - 2) % mod);
	return 0;
}
//话说为什么这个代码能过啊...
//感觉数据范围会炸的可以看一眼快读
//数据里面好像并没有无解的数据点

扩展欧几里得的写法

代码

/*
  Time: 6.19
  Worker: Blank_space
  Source: P2613 【模板】有理数取余
*/
/*--------------------------------------------*/
#include<cstdio>
#define int long long
/*--------------------------------------头文件*/
const int mod = 19260817;
/*------------------------------------常量定义*/
int a, b, d, x, y;
/*------------------------------------变量定义*/
inline int read() {
	int x = 0, f = 1; char ch = getchar();
	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9') {x = ((x << 3) + (x << 1) + (ch ^ 48)) % mod; ch = getchar();}
	return x * f;
}
/*----------------------------------------快读*/
void exgcd(int _a, int _b, int &_d, int &_x, int &_y) {
	if(_b) exgcd(_b, _a % _b, _d, _y, _x), _y -= _x * (_a / _b);
	else _d = _a, _x = 1, _y = 0;
}
/*----------------------------------------函数*/
signed main() {
	a = read(); b = read(); exgcd(b, mod, d, x, y); x /= d; x = (x % mod + mod) % mod; printf("%lld", a * x % mod);
	return 0;
}


扩展欧拉定理

模 \(p\) 意义下 对于 \(a^b\) 有

\(a^b \equiv \begin{cases}a^b & b < \varphi(p) \\ a^{b\ mod\ \varphi(p) + \varphi(p)} & b \geq \varphi(p) \end{cases}\)

众所周知 有一个叫欧拉筛的东西 虽然对这个题并没有什么用

题目: 扩展欧拉定理

很惊喜的发现 \(b\) 后面跟着一大坨令人恶心的东西 然后又发现直接筛欧拉函数复杂度就会爆炸 但是这里只需要求一个数的欧拉函数值 根据前面 \(\varphi(n) = n\prod(1 - \frac 1{p_i})\) 考虑对 \(n\) 质因数分解 直接试除

代码

/*
  Time: 6.19
  Worker: Blank_space
  Source: P5091 【模板】扩展欧拉定理
*/
/*--------------------------------------------*/
#include<cstdio>
#define int long long
/*--------------------------------------头文件*/
const int INF = 1e14;
/*------------------------------------常量定义*/
inline void File() {
	freopen(".in", "r", stdin);
	freopen(".out", "w", stdout);
}
/*----------------------------------------文件*/
int a, b, m, phi = INF, ans = 1;
bool flag;
/*------------------------------------变量定义*/
inline int read() {
	int x = 0, f = 1; char ch = getchar();
	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9') {
		x = (x << 3) + (x << 1) + (ch ^ 48);
		if(x >= phi) flag = 1, x %= phi; ch = getchar();
	}
	return x * f;
}
/*----------------------------------------快读*/
int power(int _a, int _b, int res = 1) {for(; _b; _a = _a * _a % m, _b >>= 1) if(_b & 1) res = res * _a % m; return res;}
/*----------------------------------------函数*/
signed main() {
	a = read(); m = read(); phi = m; int tmp = m;
	for(int i = 2; i * i <= m; i++) if(!(tmp % i))
	{
		phi -= phi / i;
		while(!(tmp % i)) tmp /= i;
	}
	if(tmp > 1) phi -= phi / tmp; b = read() + flag * phi;
	printf("%lld", power(a, b));
	return 0;
}

题目: 上帝与集合的正确用法(待完成)


posted @ 2021-06-19 22:03  Blank_space  阅读(614)  评论(8)    收藏  举报
// // // // // // //