Pixiv - Miracle
7-数论
1066 字
5 分钟
7-数论
数论
中国剩余定理(CRT)
扩展CRT
using ll = long long;
// 扩展gcdll exgcd(ll a, ll b, ll &x, ll &y) { if (!b) { x = 1; y = 0; return a; } ll x1, y1; ll g = exgcd(b, a % b, x1, y1); x = y1; y = x1 - a / b * y1; return g;}
// 扩展CRT// a[i] ≡ x (mod m[i])// 返回 (x, lcm) 或 (-1, -1) 表示无解pair<ll, ll> excrt(vector<ll>& a, vector<ll>& m) { ll A = a[0], M = m[0];
for (int i = 1; i < a.size(); ++i) { ll a2 = a[i], m2 = m[i];
ll x, y; ll g = exgcd(M, m2, x, y);
ll c = a2 - A; if (c % g != 0) return {-1, -1}; // 无解
// 防溢出写法 ll mod = m2 / g; x = (__int128)x * (c / g) % mod;
A = A + x * M; M = M / g * m2;
A = (A % M + M) % M; }
return {A, M};}快速乘
unsigned long long 溢出相当于对取余
ll qmul(ll a, ll b, ll p) { ll q = (ld)a / p * b; ll res = (ull)a * b - (ull)q * p; return (res + p) % p;}快速幂
ll qmi(ll a, ll b, ll p) { ll res = 1 % p; while (b) { if (b & 1) res = res * a % p; a = a * a % p; b >>= 1; } return res;}扩展欧几里得定理(EXGCD)
求as + bt = gcd(a, b)的s和t
25s + 11t = gcd(11, 3)
11s1 + 3t1 = gcd(3, 2)
3s2 + 2t2 = gcd(2, 1)
2s3 + t3 = gcd(1, 0)
s4 = 1, t4 = 0
s = t’, t = s’ - qt’
pair<int, int> extgcd(int a, int b) { if (!b) return make_pair(1, 0); auto [s, t] = extgcd(b, a % b); return make_pair(t, s - a / b * t);//t * (1,s/t-a/b)}欧拉定理
gcd(a, m) = 1
费马小定理
本身为欧拉定理的特例
p是素数,gcd(a, m) = 1, 有
既约剩余系 * 任意数a的数是既约剩余系的重排列
乘法在同余等价关系上有幺元,当乘数和模数互素时有逆元
gcd(a, n) = 1
贝祖定理 as + nt = 1,则有
则a有逆元s,同时可以进行同余除法
命题
设模 ( n ) 的既约剩余系为:
其中:
若整数 ( a ) 满足:
则集合:
仍然是模 ( n ) 的一个既约剩余系(只是一个重排列)。
证明思路
分三步:
第一步:仍然互质
因为:
则:
理由:
因此:
故:
所以每个元素仍在单位群里。
第二步:不会产生重复
假设:
则:
因为:
所以 ( a ) 在模 ( n ) 下可逆。乘以 ( a^{-1} ) 得:
但既约剩余系中本来互不相同,因此:
所以不会出现重复。
第三步:个数相同
原集合有:
个元素。
现在:
- 每个元素仍互质
- 无重复
- 个数不变
因此必然是既约剩余系的一个排列。
质数
筛法
线性筛法
int primes[N], idx;bool vis[N];void getp(int n) { memset(primes, 0, sizeof primes); primes[1] = 0; for (int i = 2; i <= n; ++i) { if (!vis[i]) primes[++idx] = i; for (int j = 1; i * primes[j] <= n; ++j) { vis[i * primes[j]] = 1; if (i % primes[j] == 0) break; } }}埃筛
int primes[N], idx;bool vis[N];void getp(int n) { for (int i = 2; i <= n; ++i) { if (vis[i]) continue; primes[idx++] = i; for (int j = i; j <= n / j; ++j) { vis[j * i] = 1; } }}约数
质因数分解
纯暴力
unordered_map<int, int> pcnt;
void getfactor(int n) { for (int i = 2; i <= n / i; ++i) { while (n % i == 0) { ++pcnt[i]; n /= i; } }}阶乘的质因数分解
约数计算
欧拉函数
性质
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
随机文章 随机推荐