数论~持续更新

本文详细介绍了数论中的重要算法,包括快速幂、快速乘、埃氏筛与欧拉筛等质数生成方法,以及欧几里得算法、裴蜀定理、扩展欧几里得等数论原理。此外,还探讨了逆元、费马小定理及其应用,为理解数论基础和解决相关问题提供指导。
摘要由CSDN通过智能技术生成

 

快速幂 :

ll calc(ll x,ll y){
	ll ans = 1;
	while(y){
		if(y & 1) ans = (ans * x) % k;
		x = (x * x) % k;
		y >>= 1;
	}
	return ans % k;
}

时间复杂度是logn;

运用二进制拆分;

快速乘:

应用于大整数相乘时,由于相乘后的结果会爆掉long long,所以化乘法为加法,然后取模。

a * b的实质是b个a相加,可以参考快速幂的思想运算。

a * b = 2 * (a * b / 2); b为偶数

a * b = 2 * (a * (b - 1) / 2 + a) ,b为奇数.

将b二进制拆分,然后进行加法即可。

ll ksc(ll a,ll b){
	ll ans = 0;
	while(b){
		if(b & 1){
			ans = (ans + a) % mod;
			b --;
		}
		b >>= 1;
		a = (a * 2) % mod;
	}
	return ans;
}

 

埃氏筛:

非常朴素的筛法,复杂度是O(nlogn)的。

 

 

欧拉筛:

void euler(){
	not_p[0] = not_p[1] = 1;
	for(int i = 2;i <= n;i ++){
		if(!not_p[i]) p[++ tot] = i;
		for(int j = 1;j <= tot && p[j] * i <= n;j ++){
			not_p[i * p[j]] = 1;
			if(i % p[j] == 0) break;
		}
	}
	return;
}

关键在于跳出循环的条件的理解,i % p[j] == 0,这句话决定了所有的数都只能被他最小的质因数筛去。

p[i] 为 n的最小质因数;

考虑 n = m * p[i] ,n = m1 * p[i + k],则p[i] < p[i + k];

n 只会被p[i] 筛去,因为p[i] != p[i + k];

m = p[i + k] * m1 / p[i] ,即p[i] | m1;

则n = p[i] * p[i + k] * t ,其中 t = m1 / p[i];

则n仍会被p[i]筛去;

而对于i * p[i + k] 这些数则在循环到后面时被他的最小质因数筛去;

因为,每个数只会被他最小的质因数筛去,所以复杂度为O(n);

欧几里得:

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

gcd(a,b) = gcd(b,a % b)

证明:

不妨设 a > b

假设d为gcd (a,b)的一个公约数,则d|a d|b

设 r = a % b

r= a - k * b 

r/d = a/d - (k * b) /d = m

m为整数

所以d|r 

因此两者公约数相等,最大公约数也相等

当b为0是说明在递归的上一层中,a = k * b,则显然b为最大公约数。

 

裴蜀定理:

若a,b是整数,且gcd(a,b)=d,那么对于任意的整数x,y,ax+by都一定是d的倍数,特别地,一定存在整数x,y,使ax+by=d成立即d不是gcd(a,b)的倍数时,ax+by=d无。

推论:gcd(a,b)=1时,ax+by=1才有解(有逆元的充要条件)

 

扩展欧几里得:

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

求解ax + by = n的二元一次方程的解.

a,x,b,y是整数,则n是gcd(a,b)的倍数;

a / gcd * x + b / gcd * y = n / gcd;

显然左边是整数,则右边必然也是整数,否则无整数解;

先考虑求解ax1 + by1 = gcd(a,b)的解;

ax1 + by1 = gcd(a,b) = gcd(b,a % b) = bx2 + (a % b)y2;

a % b = a - a / b * b;

化简得 :
x1 = y2;

y2 = x2 - a / b * y2;

则最后的答案是x = x1 * n / gcd(a,b) , y = y1 * n / gcd(a,b);

应用 : 求二元一次方程,一元同余方程的多组解;

逆元:

ax mod m = 1 mod m,则称x是a mod m时的逆元;

求解逆元的方法:

1、线性递推求逆元。

2、exgcd求解。

3、费马小定理。

逆元的应用:

1、大整数除法取模

由于除法在mod的时候不支持结合律,所以在大数相除的时候,考虑到(a / b)mod m时会损失大量的精度,由此,可以用逆元将除法转化为乘法。

设x为b mod m时的逆元,(a  \ b)mod m = (a \ b) mod m * ( (b * x) mod m ) = (a * x) mod m;

2、求解二元一次方程的解;

设A 是 a mod m时的逆元,对于二元一次方程有:

ax + my = b;

转化为求

a0 * x + m0 * y = b / gcd(a,b);

a0 = a / gcd(a,b);

m0 = m / gcd(a,b);

即求 a0 * x0 + m0 * y0 = 1,且满足a0 和 m0互质;

等价于 a0 * x0 mod m0 = 1 mod m0;

x0 = A 

x = x0 * b 

y = y0 * b

 

费马小定理:

a ^ (p - 1) mod p = 1 mod p; 其中a 和 p互质;

证明:
1.1引理1  : a mod m = b mod m;

设c 与 m互质 ,则满足 a * c mod m = b * c mod m;

1.1证明 : 显然

从模n的每个剩余类中各取一个数,得到一个由n个数组成的集合,叫做模n的一个完全剩余系。——百度百科

1.2引理:若 0,1,2,3, …… m - 1 是 a mod m的完全剩余系;

则 0 * c, 1 * c, 2 * c,3 * c …… (m - 1)* c也是a mod m的完全剩余系,c 与 m 互质。

1.2证明:假设序列2中存在两个数i, j ,使得 i * c mod m = j * c mod m。

由引理1.1知 i = j,不符,假设不成立,所以序列2中的数在mod m后是互不相同的m个数,由于mod m后的值不可能大于m,所以序列2是 a mod m的完全剩余系,但注意并不与等式左边一一对应;

因此

序列1 : 1,2,3,4……m - 1;

序列2 :1 * c,2 * c,3 * c,4 * c …… (m - 1)* c 

满足 1 * 2 * 3 * 4 …… * (m - 1) mod m =  c * 2 * c * 3 * c * 4 …… * (m - 1)* c mod m;

即 (m - 1)! mod m = (m - 1)! * c ^ (m - 1) mod m;

即 a ^ (p - 1) mod p = 1 mod p ,p与m互质; 

显然,a ^ (p - 2) 是a mod p时的逆元;

求解二元一次方程的解的两种方法:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a,b,c;

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

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

int ksm(int a,int x){
	int tmp = 1;
	while(x){
		if(x & 1) tmp = (tmp * a) % b;
		a = (a * a) % b,x >>= 1;
	}
	return tmp % b;
}

void solve(){
	int a0,b0,x,y,ni,g;
	cin >> a >> b >> c;
	g = gcd(a,b),a0 = a / g,b0 = b / g,c /= g;
	if(b0 - 2 > 0){
		ni = ksm(a0,b0 - 2);
		cout << ni * c<< " " << (c - a0 * ni * c) / b0 << endl;
	}
	exgcd(a,b,x,y);
	cout << x * c << " " << y * c << endl;
	return;
}

int main(){
	solve();
	return 0;
}

欧拉定理 和 欧拉函数:

Miller-Rabin素数测试:

约数定理与约数和定理:

威尔逊定理:

斯特林公式:

勒让德定理:

欧拉降幂:
 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值