算数基本定理及其推论, 质因数分解
算数基本定理及其推论
- 算数基本定理
任何一个大于1的自然数N,如果N不为质数,都可以唯一分解成有限个质数的乘积
,这里
均为质数,其诸指数是正整数
这样的分解称为N的标准分解式。
- 推论
1.算数基本定理中N的正约数个数为:
2.算数基本定理中N的所有正约数的和为:
参考自文章且文章中包括以上两条推论的应用。
质因数分解
void f(int n)
{
if(n<=1)//n没有因数
{
cout<<n;
return;
}
int a=2;
while(a*a<=n)
{
while(n%a==0)
{
cout<<a<<endl;
n=n/a;
}
a++;
}
}
GCD LCM相关
如何计算
ll gcd(ll a,ll b)//最大公约数
{
if(b==0)return a;
else return gcd(b,a%b);
}
ll lcm(ll a,ll b)//最小公倍数
{
return a*b/gcd(a,b);
}
一些结论
-
gcd(a1,a2,a3…,an)=gcd(a1,a2−a1,a3−a2,…,an−an−1)
-
gcd(a1,a2,…,an) = gcd(a1,gcd(a2,…,an))
-
lcm(a/b,a/c)=a/gcd(b,c)
-
lcm(a,b)=a×b/gcd(a,b)
-
gcd(lcm(a,b),lcm(a,c))=gcd(a×b/gcd(a,b),a×c/gcd(a,c))=a×gcd(b/gcd(a,b),c/gcd(a,c))=a×gcd(b,c)/gcd(a,b,c)
-
gcd(lcm(a1,a2),lcm(a1,a3),lcm(a1,a4),…,lcm(a1,an))=lcm(a1,gcd(a2,a3,a4,…,an)
应用如下:
- 训练题B(运用结论6)
(除了暴力 想不到别的,所以参考了网络上的题解)
思路:由结论6可知只要先求出后缀gcd,gcdm=lcm(am,gcd(a(m+1),a(m+2),a(m+3),…,an)最终结果就是gcd(gcd1,gcd2,gcd3,…,gcdn)
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
ll gcd(ll a,ll b)
{
if(b==0)return a;
else return gcd(b,a%b);
}
ll lcm(ll a,ll b)
{
return a*b/gcd(a,b);
}
ll a[200010];
ll l[200010];
int main()
{
int n;
cin>>n;
for(int i=1; i<=n; i++) cin>>a[i];
for(int i=n; i>=1; i--) l[i]=gcd(a[i],l[i+1]);
ll res=0;
for(int i=1; i<=n; i++)res=gcd(res,lcm(a[i],l[i+1]));
cout<<res<<endl;
return 0;
}
- 训练题D(虽然test4 WA了,还是先占个坑之后来填
咕咕咕)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[400010];
ll gcd(ll a,ll b)
{
if(b==0)return a;
else return gcd(b,a%b);
}
ll ngcd(int n)
{
ll ans=a[0];
for(int i=1;i<n;i++)
{
ans=gcd(ans,a[i]);
}
return ans;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%lld",&a[i]);
ll g=ngcd(n);
int cnt=0;
for(int i=1;i*i<=g;i++)
{
if(g%i==0)cnt++;
if(i*i<g)cnt++;
}
cout<<cnt<<endl;
return 0;
}
互质 欧拉函数
互质
参考自这是链接!
定义:如果两个正整数,除了1以外,没有其他公因子,我们就称这两个数是互质的。
关于互质关系,不难得到以下结论:
- 任意两个质数构成互质关系,比如2和3。
- 一个数是质数,另一个数只要不是前者的倍数,两者就构成互质关系,比如2和9。
- 如果两个数之中,较大的那个数是质数,则两者构成互质关系,比如17和6。
- 1和任意一个自然数是都是互质关系。
- p是大于1的整数,则p和p-1构成互质关系。
- p是大于1的奇数,则p和p-2构成互质关系。
欧拉函数
基本概念:1~N中与N互质的数的个数
在上面的算术基本定理中:N = (p1a1) * (p2a2) * … *(pnan),则该数的欧拉函数为φ(N)=N * (1-1/p1) * (1-1/p2) * … * (1-1/pn)。
code from第25小时
- 求N的欧拉函数 O(sqrt(N))
int get_euler(int a) {
long long res = a; // 存储答案
for (int i = 2; i <= a / i ;++i) { // 求出小于等于sqrt(a)的质数
if (a % i == 0) {
res = res * (i - 1) / i; // 欧拉函数公式求答案
while (a % i == 0) a /= i;
}
}
if (a > 1) res = res * (a - 1) / a;
return res;
}
- 求1~N的欧拉函数和 O(N)
phi[1] = 1;
long long res = 0;
for (int i = 2; i <= n; ++i ) { // 求质数
if (!st[i]) { // 没记录就标记这个质数
prime[cnt++] = i;
phi[i] = i - 1; // 质数的欧拉函数为本身减一
}
for (int j = 0; prime[j] <= n / i; ++j) { // 枚举所有的质数
st[prime[j] * i] = 1;
if (i % prime[j] == 0 ) { // 如果i能够整除pj
phi[i * prime[j]] = prime[j] * phi[i]; // phi(i * pj) = pj * phi[i]
break;
}
phi[i * prime[j]] = phi[i] * (prime[j] - 1); // phis(i * pj) = phi(i) * (pj - 1)
}
}
for (int i = 1; i <= n; ++i) res += phi[i]; // 累加每个数的欧拉函数