数论gcd

本文介绍了GCD的基本运算原理,包括裴蜀定理及其扩展,展示了如何通过扩展gcd求解逆元问题。同时涵盖了欧拉函数的性质,如互质数的欧拉函数乘积定理,以及计算欧拉函数的方法。重点讲解了与整数分解和逆元相关的算法实现,适合对数论和算法基础感兴趣的读者。

gcd基本运算

gcd(a,b)=gcd(a%b,b)gcd\left( a,b \right) =gcd\left( a\%b,b \right)gcd(a,b)=gcd(a%b,b)

裴蜀定理

对于给定的正整数a,b,方程 a∗x+b∗y=ca * x+b * y=cax+by=c有解的充要条件为cccgcd(a,b)gcd(a,b)gcd(a,b)的整数倍。根据逆元定义aa∗≡1(mod b)a a^{*}\equiv 1(mod\ b)aa1(mod b),则
aa∗−bk=1a a^{*}-b k=1aabk=1
c=1时表明a,b互质是逆元存在的必要条件。同样可以证明:a,b互质是 a 在模 b 下存在逆元的充分条件。

扩展gcd

求解gcd(a,b)=ax+bygcd(a, b)=a x+b ygcd(a,b)=ax+by中的x、yx、yxy
x=y′ 且 y=x′−⌊ab⌋y′x=y^{\prime} \text { 且 } y=x^{\prime}-\left\lfloor\frac{a}{b}\right\rfloor y^{\prime}x=y  y=xbay

int exgcd(int a, int b, int& x, int& y) {
    if(a < b) return exgcd(b, a, y, x);
    if(b == 0) {
        x = 1; y = 0;
        return a;
    } else {
        int x1;
        int d = exgcd(b, a % b, x1, x);//算出x=y'
        y = x1 - a / b * x;//算出y=x1-a/b*y'
        return d;
    }
}

欧拉函数

φ(x)=x∏i=1n(1−1pi)\varphi(x)=x \prod_{i=1}^{n}\left(1-\frac{1}{p_{i}}\right)φ(x)=xi=1n(1pi1)其中pip_{i}pixxx的质因子

① 当m,nm,nm,n互质时,有phi(m∗n)=phi(m)∗phi(n)phi(m*n)= phi(m)*phi(n)phimn=phimphin

② 若ii%p==0i,有phi(i∗p)=p∗phi(i)phi(i*p) = p * phi(i)phiip=pphi(i)

③ 对于互质的a和n, aφ(n)≡1( mod  n)a^{\varphi(n)} \equiv 1( \bmod\ n)aφ(n)1(mod n)
(特别地,当n为质数时,phi(n)=n−1phi(n)=n-1phin=n1,此时逆元为an−2a^{n-2}an2,即费马小定理)

④ 当n为奇数时,phi(2n)=phi(n)phi(2n)=phi(n)phi(2n)=phi(n)

⑤ 若x与p互质,则p-x也与p互质,因此小于p且与p互质的数之和为phi(x)∗x/2phi(x)*x/2phi(x)x/2

⑥N>1,不大于N且和N互素的所有正整数的和是 1/2∗N∗eular(N)1/2 *N *eular(N)1/2Neular(N)

⑦若(N%a == 0 && (N/a)%a==0) 则有:E(N)=E(N/a)∗aE(N)=E(N/a)*aE(N)=E(N/a)a;

⑧若(N%a==0 && (N/a)%a!=0) 则有:E(N)=E(N/a)∗(a−1)E(N)=E(N/a)*(a-1)E(N)=E(N/a)(a1);

∑d∣nφ(d)=n\sum_{d \mid n} \varphi(d)=ndnφ(d)=n
求单个

int pi(int x)
{
	int ans=x;
	for(int i=2;i*i<=n;i++)
	{
		if(n%i==0)
		{
			ans=ans/i*(i-1);
			while(n%i==0)
			n/=i;
		}
	}
	if(n>1)//有一个等于本身的质因子
	ans=ans/n*(n-1);
	return ans
}

求1–n

int primes[N], cnt;     // primes[]存储所有素数
int euler[N];           // 存储每个数的欧拉函数
bool st[N];         // st[x]存储x是否被筛掉


void get_eulers(int n)
{
    euler[1] = 1;
    for (int i = 2; i <= n; i ++ )
    {
        if (!st[i])
        {
            primes[cnt ++ ] = i;
            euler[i] = i - 1;
        }
        for (int j = 0; primes[j] <= n / i; j ++ )
        {
            int t = primes[j] * i;
            st[t] = true;
            if (i % primes[j] == 0)
            {
                euler[t] = euler[i] * primes[j];
                break;
            }
            euler[t] = euler[i] * (primes[j] - 1);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值