数论中的各种定理(待更新)

本文介绍了数论中的几个重要定理,包括费马小定理、欧拉定理、威尔逊定理以及中国剩余定理,并提供了一个解决一元线性同余方程组的C++代码示例。

本篇博客仅仅是搜罗各种数论中的定理便于日常使用,具体的证明还需从网络中获得,特此告知

1.费马小定理

内容:假如a是整数,p是质数,且a,p互质(即两者最大公约数为1),那么a的(p-1)次方除以p的余数恒等于1


2.欧拉定理(其实包含了费马小定理)


3.威尔逊定理


4.中国剩余定理(孙子定理)

一元线性同余方程组

模板:

/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define eps 1e-8
#define LL long long
#define bitnum(a) __builtin_popcount(a)
using namespace std;
const int N = 105;
const int M = 100005;
const int inf = 1000000007;
const int mod = 1000000007;
int group;
LL n[N],a[N];
LL Egcd(LL a,LL b,LL &x,LL &y)
{
    if(b==0)
    {
        x=1,y=0;
        return a;
    }
    LL d,tp;
    d=Egcd(b,a%b,x,y);
    tp=x;
    x=y;
    y=tp-a/b*y;
    return d;
}
LL solve()
{
    int i;
    bool flag = false;
    LL n1 = n[0], n2, b1 = a[0], b2, bb, d, t, k, x, y;
    for (i = 1; i < group; i++)
    {
        n2 = n[i], b2 = a[i];
        bb = b2 - b1;
        d = Egcd (n1, n2, x, y);
        if (bb % d)     //模线性解k1时发现无解
        {
            flag = true;
            break;
        }
        k = bb / d * x;    //相当于求上面所说的k1【模线性方程】
        t = n2 / d;
        if (t < 0) t = -t;
        k = (k % t + t) % t;    //相当于求上面的K`
        b1 = b1 + n1*k;
        n1 = n1 / d * n2;
    }
    if(flag)
        return -1;     //无解
/******************求正整数解******************/
    if(b1==0)    //如果解为0,而题目要正整数解,显然不行
        b1=n1;    //n1刚好为所有ni的最小公倍数,就是解了
/******************求正整数解******************/
    return b1;    //形成的解:b1, b1+n1, b1+2n1,..., b1+xni...
}
int main()
{
    int i;
    scanf("%d",&group);
    for(i=0;i<group;i++)
    {//X mod n[i] = a[i] ,n[i]两两之间不一定互质做法
        scanf ("%lld%lld",&n[i],&a[i]);
        a[i]%=n[i];
    }
    printf ("%lld\n",solve());
    return 0;
}
菜鸟成长记

<think>首先,用户查询是:“我想查找ACM数论相关的代码模板 请问ACM数论代码模板”。我需要基于系统级指令和用户提供的引用来回答。 系统级指令关键点: - 所有行内数学表达式使用$...$格式。 - 独立公式使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 引用末尾添加标识如[^1]。 用户提供了几个引用: - [^1]:关于模逆元的计算,使用快速幂或扩展欧几里得算法。 - [^2]:莫比乌斯反演的题目和公式。 - [^3]:预处理阶乘和逆元,用于组合数的计算。 - [^4]:欧拉函数的定义、性质和计算算法。 用户的上一次查询是“查找ACM数论相关的代码模板”,所以我需要提供一个清晰的、结构化的回答,涵盖常见的ACM数论模板。 核心元素: - **模逆元计算**:快速幂方法(qmi)和扩展欧几里得方法。 - **组合数计算**:预处理阶乘和其逆元。 - **欧拉函数**:朴素方法和线性筛法。 - **快速幂算法**:用于快速计算幂模素数。 - **其他常见模板**:如最大公约数(GCD)、质因数分解、线性筛质数等。 由于引用中没有提到所有,我应该补充常见模板,确保回答全面但基于引用优先。 结构回答: 1. **引言**:简要介绍ACM数论常见算法。 2. **核心模板**:逐一列出代码模板。 3. **格式**:代码块使用Markdown格式,数学表达式正确。 4. **引用**:在相关部分添加引用标识。 5. **相关问题**:结束时生成相关问题。 列出模板: - **快速幂算法**:引用[^1]和[^3]中都有。 - **模逆元计算**:引用[^1]。 - **组合数计算**:引用[^3]。 - **欧拉函数计算**:引用[^4]。 - **其他**:GCD、线性筛质数、扩展欧几里得(引用[^1]中提到)。 添加扩展欧几里得,因为它用于模逆元。 回答结构: - 逐步呈现每个模板。 - 每个模板先简短描述,然后代码块。 - 确保LaTeX正确。 数学表达式: - 行内:如$gcd(n, p) = 1$。 - 独立:如欧拉函数性质。 生成相关问题: - 如ACM数论的应用、优化等。 最终输出: - 中文回答。 - 相关问题列表。 </think>以下是针对ACM数论常见代码模板的整理。ACM数论题目通常涉及质数、模运算、组合数学等核心算法。我基于您提供的引用内容(参考[^1][^2][^3][^4]),并结合ACM竞赛的常见需求,总结了以下关键模板。模板均使用C++语言实现,并确保语法正确。每个模板包括简要说明、适用条件和代码实现。 ### 1. **快速幂算法** 快速幂用于高效计算 $a^k \mod p$,时间复杂度 $O(\log k)$。适用条件:$p$ 为质数(非质数时需用扩展欧几里得)。 ```cpp typedef long long LL; LL qmi(LL a, LL k, LL p) { // a: 底数, k: 指数, p: 模数 LL res = 1 % p; while (k) { if (k & 1) res = res * a % p; a = a * a % p; k >>= 1; } return res; } /* 示例:计算 2^100 mod 1000000007 qmi(2, 100, 1000000007); */ ``` ### 2. **模逆元计算** 模逆元用于求解 $n^{-1} \mod p$(即 $n \cdot inv \equiv 1 \mod p$)。方法包括快速幂逆元(要求 $p$ 质数且 $gcd(n, p) = 1$)和扩展欧几里得逆元(通用)。 - **快速幂逆元**(引用[^1]): ```cpp LL inv(LL n, LL p) { // n: 待求逆元的数, p: 模数 return qmi(n, p - 2, p); // 利用费马小定理 } ``` - **扩展欧几里得逆元**(引用[^1]): ```cpp LL exgcd(LL a, LL b, LL &x, LL &y) { // 求解 ax + by = gcd(a, b),返回gcd if (b == 0) { x = 1, y = 0; return a; } LL d = exgcd(b, a % b, y, x); y -= a / b * x; return d; } LL inv_exgcd(LL n, LL p) { LL x, y; exgcd(n, p, x, y); // 解 nx + py = 1 return (x % p + p) % p; // 确保非负 } ``` ### 3. **组合数计算** 预处理阶乘和阶乘逆元,用于快速计算 $C_a^b \mod p$(如组合数)。时间复杂度:预处理 $O(n)$,查询 $O(1)$。适用条件:$p$ 质数且 $a, b \leq N$($N$ 为预处理上限)(引用[^3])。 ```cpp const int N = 1000010; // 预处理上限 const int mod = 998244353; // 常用模数,可替换 LL fact[N], infact[N]; // fact[i]: i的阶乘 mod p; infact[i]: i的阶乘逆元 mod p // 预处理函数 void init_comb() { fact[0] = infact[0] = 1; for (int i = 1; i < N; i++) { fact[i] = fact[i - 1] * i % mod; infact[i] = infact[i - 1] * qmi(i, mod - 2, mod) % mod; // 使用快速幂求逆元 } } // 计算组合数 C(a, b) mod p LL comb(int a, int b) { if (b < 0 || b > a) return 0; return fact[a] * infact[b] % mod * infact[a - b] % mod; } ``` ### 4. **欧拉函数** 欧拉函数 $\phi(n)$ 计算小于等于 $n$ 且与 $n$ 互质的数的个数。常用方法:朴素法 ($O(\sqrt{n})$ ) 和线性筛法 ($O(n \log \log n)$ )(引用[^4])。 - **朴素法**(单次查询): ```cpp int euler(int n) { int res = n; for (int i = 2; i * i <= n; i++) { if (n % i == 0) { res = res / i * (i - 1); // 防止溢出 while (n % i == 0) n /= i; } } if (n > 1) res = res / n * (n - 1); return res; } ``` - **线性筛法**(批量预处理): ```cpp const int Max = 1000010; // 预处理上限 int euler_phi[Max]; void init_euler() { for (int i = 1; i < Max; i++) euler_phi[i] = i; for (int i = 2; i < Max; i++) { if (euler_phi[i] == i) { // i 是质数 for (int j = i; j < Max; j += i) { euler_phi[j] = euler_phi[j] / i * (i - 1); // 更新欧拉函数值 } } } } ``` ### 5. **莫比乌斯反演相关** 莫比乌斯函数常用于处理数论求和问题(如引用[^2]中 $\sum \text{lcm}(a_i, a_j)$)。包括莫比乌斯函数 $\mu(n)$ 的预处理。 ```cpp const int MAXN = 1000010; int mu[MAXN]; // 莫比乌斯函数数组 vector<int> primes; // 存储质数 bool is_prime[MAXN]; void init_mobius() { fill(is_prime, is_prime + MAXN, true); mu[1] = 1; for (int i = 2; i < MAXN; i++) { if (is_prime[i]) { primes.push_back(i); mu[i] = -1; // 质数的莫比乌斯函数值为 -1 } for (int j = 0; j < primes.size() && i * primes[j] < MAXN; j++) { is_prime[i * primes[j]] = false; if (i % primes[j] == 0) { mu[i * primes[j]] = 0; // 有平方因子 break; } else { mu[i * primes[j]] = -mu[i]; // 积性函数性质 } } } } ``` ### 6. **其他基础模板** - **最大公约数 (GCD)**: ```cpp LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; } ``` - **最小公倍数 (LCM)**: ```cpp LL lcm(LL a, LL b) { return a / gcd(a, b) * b; // 避免溢出 } ``` - **质数筛法 (埃氏筛)**: ```cpp const int MAX = 1000010; bool is_prime[MAX]; void init_primes() { fill(is_prime, is_prime + MAX, true); is_prime[0] = is_prime[1] = false; for (int i = 2; i * i < MAX; i++) { if (is_prime[i]) { for (int j = i * i; j < MAX; j += i) { is_prime[j] = false; } } } } ``` ### 注意事项 - 所有模板均假设模数 $p$ 在合理范围内(通常 $p \leq 10^9$),并使用 `long long` 防溢出。 - 在ACM中,欧拉定理和指数降幂公式可用于优化幂运算(引用[^4]):若 $a$ 和 $n$ 互质,则 $a^k \mod n = a^{k \mod \phi(n)} \mod n$。 - 这些模板覆盖了大部分ACM数论题目,如莫比乌斯反演、组合计数和模方程求解[^1][^2][^3][^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值