2021_GDUT_Number theory

最大公约数:

定义:

若自然数d同时是自然数a和b的约数,则称d是a和b的公约数。a和b的公约数中最大的数g则称为a和b的最大公约数,即为gcd(a,b)。

欧几里得算法

描 述 : ∀ a , b ∈ N , b ≠ 0 , g c d ( a , b ) = g c d ( b , a % b ) ; 描述:\forall a,b \in N,b \ne 0,gcd(a,b) = gcd(b,a\%b); :a,bN,b=0,gcd(a,b)=gcd(b,a%b);
证 明 : 若 a < b , 则 g c d ( b , a % b ) = g c d ( b , a ) = g c d ( a , b ) ; 若 a > = b , 设 a = q ∗ b + r , 其 中 b ∈ [ 0 , b ) , 显 然 r = a % b , 设 g = g c d ( a , b ) , 则 有 g ∣ a , g ∣ q ∗ b , 则 有 g ∣ ( a − q ∗ b ) , 即 g ∣ r , 因 此 g 也 为 r 和 b 的 最 大 公 约 数 , 即 g c d ( a , b ) = g c d ( b , a % b ) , 证 毕 ! 证明:若a < b,则gcd(b,a\%b) = gcd(b,a) = gcd(a,b);若a>=b,\\设a = q*b+r,其中b\in[0,b),显然r = a\%b,设g = gcd(a,b),则有\\g|a,g|q*b,则有g|(a-q*b),即g|r,因此g也为r和b的最大公约数,\\即gcd(a,b) = gcd(b,a\%b),证毕! :a<b,gcd(b,a%b)=gcd(b,a)=gcd(a,b);a>=b,a=qb+r,b[0,b),r=a%b,g=gcd(a,b),ga,gqb,g(aqb),gr,grb,gcd(a,b)=gcd(b,a%b),!

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

最小公倍数

定义:

若自然数m同时自然数a,b的倍数,则称m是a,b的公倍数。在a和b中所有的公倍数最小的一个则成为最小公倍数,记为lcm(a,b)。易证lcm(a,b) = a*b/gcd(a,b)。

例题讲解:

For a given positive integer n denote its k-rounding as the minimum positive integer x, such that x ends with k or more zeros in base 10 and is divisible by n.
For example, 4-rounding of 375 is 375·80 = 30000. 30000 is the minimum integer such that it ends with 4 or more zeros and is divisible by 375.
Write a program that will perform the k-rounding of n.

分析:题目等效于求出n和pow(10,k)的最小公约数。

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
int gcd(int a,int b)
{
	if(!b) return a;
	else return gcd(b,a%b);
}
ll lcm(int a,int b)
{
	return (ll)a*b/gcd(a,b);
}
int main()
{
	int n,k;cin >> n >> k;
	cout << lcm(n,pow(10,k)) << endl;
	return 0;
}

同余

定义

若 整 数 a , b 除 以 正 整 数 m 的 余 数 相 等 , 则 称 a , b 模 m 同 余 , 记 为 a ≡ b ( m o d   m ) 若整数a,b除以正整数m的余数相等,则称a,b模m同余,记为a\equiv b(mod\ m) a,bm,a,bm,ab(mod m)

欧拉定理

若 正 整 数 a , n 互 质 , 则 a φ ( n ) ≡ 1 ( m o d   n ) , 其 中 φ ( n ) 为 欧 拉 函 数 . 证 明 : 设 n 的 简 化 剩 余 系 为 { b 1 ‾ , b 2 ‾ , . . . , b φ ( n ) ‾ } 。 对 ∀ b i , b j , 若 a ∗ b i ≡ a ∗ b j ( m o d   n ) , 则 有 a ∗ ( b i − b j ) ≡ 0 ( m o d   n ) . 因 为 a , n 互 质 , 所 以 ( b i − b j ) ≡ 0 ( m o d   n ) , 即 b i ≡ b j ( m o d   n ) . 故 当 b i ≠ b j 时 , a b i , a b j 也 代 表 不 同 的 同 余 类 。 天 堂 > > > 制 造 > > > 证 毕 ! 若正整数a,n互质,则a^{\varphi(n)} \equiv1(mod\ n),其中\varphi(n)为欧拉函数.\\证明:设n的简化剩余系为 \{\overline{b_{1} }, \overline{b_{2} },...,\overline{b_{\varphi(n)} }\}。对\forall b_i,b_j,若\\a*b_i \equiv a*b_j(mod\ n),则有a*(b_i-b_j)\equiv 0(mod\ n).\\因为a,n互质,所以(b_i-b_j)\equiv 0(mod\ n),即b_i\equiv b_j(mod\ n).故当\\b_i\ne b_j时,ab_i,ab_j也代表不同的同余类。天堂>>>制造>>>证毕! a,n,aφ(n)1(mod n),φ(n).:n{b1,b2,...,bφ(n)}bi,bj,abiabj(mod n),a(bibj)0(mod n).a,n,(bibj)0(mod n),bibj(mod n).bi=bj,abi,abj>>>>>>

费马小定理

若 p 是 质 数 , 则 对 于 任 意 整 数 a , 有 a p ≡ a ( m o d   p ) 。 证 明 : 用 欧 拉 定 理 证 明 。 若p是质数,则对于任意整数a,有a^p\equiv a(mod\ p)。\\证明:用欧拉定理证明。 p,a,apa(mod p):

例题讲解

要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1)。

分析:费马小定理运用快速幂求逆元即可.

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int mod = 9973;
ll qpow(ll n,ll m)
{
	ll ans = 1;
	while(m)
	{
		if(m&1)
		{
			--m;
			ans *= n;
			ans %= mod;
		}
		else
		{
			m >>= 1;
			n *= n;
			n %= mod;
		}
	}
	return ans;
} 
int main()
{
	int T;cin >> T;
	while(T--)
	{
		ll a,b;cin >> a >> b;
		a %= mod;
		ll ans = a*qpow(b,mod-2);
		ans %= mod;
		cout << ans << endl;
	}
	return 0;
}

拓展欧几里得算法

对 于 任 意 正 整 数 a , b , 存 在 一 对 整 数 x , y , 满 足 a x + b y = g c d ( a , b ) . 对于任意正整数a,b,存在一对整数x,y,满足ax+by = gcd(a,b). a,b,x,y,ax+by=gcd(a,b).

int x,y;
int exgcd(int a,int b)
{
	if(!b){ x = 1,y = 0;return a;}
	int d = exgcd(b,a%b);
	int z = x,x = y,y = z-y*(a/b);
	return d;
}
例题讲解:

两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面。它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止。可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置。不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的。但是除非这两只青蛙在同一时间跳到同一点上,不然是永远都不可能碰面的。为了帮助这两只乐观的青蛙,你被要求写一个程序来判断这两只青蛙是否能够碰面,会在什么时候碰面。
我们把这两只青蛙分别叫做青蛙A和青蛙B,并且规定纬度线上东经0度处为原点,由东往西为正方向,单位长度1米,这样我们就得到了一条首尾相接的数轴。设青蛙A的出发点坐标是x,青蛙B的出发点坐标是y。青蛙A一次能跳m米,青蛙B一次能跳n米,两只青蛙跳一次所花费的时间相同。纬度线总长L米。现在要你求出它们跳了几次以后才会碰面。

分析:列出方程组后通过转化即可利用拓展欧几里得算法即可算出答案;

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
const ll INF = -1;
ll x,y;
ll gcd(ll a,ll b)
{
	if(!b) return a;
	else return gcd(b,a%b);
}
void ex_gcd(ll a,ll b)
{
	if(!b)
	{
		x = 1;
		y = 0;
		return;
	}
	ex_gcd(b,a%b);
	ll t = x;
	x = y;
	y = t-a/b*y;
	return ;
}
int main()
{
	ll d1,d2,m,n,b;cin >> d1 >> d2 >> m >> n >> b;
	ll a,c;
	if(n > m){a = n-m;c = d1-d2;}
	else {a = m-n;c = d2-d1;}
	ll g = gcd(a,b);
	ex_gcd(a,b);
	ll ans;
	if(c%g) ans = INF;
	else
		ans = (c/g*x%(b/g)+b/g)%(b/g);
	if(ans == INF)
		cout << "Impossible" << endl;
	else
		cout << ans << endl;
	return 0;
} 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值