约数
试除法求约数
1 vector<int> get_divisors(int x) 2 { 3 vector<int> res; 4 for (int i = 1; i <= x / i; i ++ ) 5 if (x % i == 0) 6 { 7 res.push_back(i); 8 if (i != x / i) res.push_back(x / i);//如果i不等于根号x说明i的相对的约数不为i 9 } 10 sort(res.begin(), res.end());//对约数进行排序 11 return res; 12 }
约数的个数和约数的和
引理:任何一个大于1的自然数 N,如果N不为质数,那么N可以唯一分解成有限个质数的乘积N=P1a1P2a2P3a3......Pnan,这里P1<P2<P3......<Pn均为质数,其中指数ai是正整数。这样的分解称为 N 的标准分解式。最早证明是由欧几里得给出的,由陈述证明。此定理可推广至更一般的交换代数和代数数论。
1 约数个数: (c1 + 1) * (c2 + 1) * ... * (ck + 1) 2 约数之和: (p1^0 + p1^1 + ... + p1^c1) * ... * (pk^0 + pk^1 + ... + pk^ck)
求约数个数
1 while(t--) 2 { 3 cin>>n; 4 for(int i=2;i<=n/i;i++) 5 while(n%i==0) 6 { 7 n/=i; 8 prime[i]++; 9 } 10 if(n>1) prime[n]++; 11 } 12 13 long long ans=1; 14 for(auto it:prime) ans=ans*(it.second+1)%mod;
求约数的和
1 while(t--) 2 { 3 cin>>n; 4 for(int i=2;i<=n/i;i++) 5 while(n%i==0) 6 { 7 n/=i; 8 prime[i]++; 9 } 10 if(n>1) prime[n]++; 11 } 12 13 long long ans=1; 14 for(auto it:prime) 15 { 16 int a=it.first,b=it.second; 17 long long temp=1; 18 for(int i=1;i<=b;i++) temp=(temp*a+1)%mod; 19 ans=(ans*temp)%mod; 20 }
欧几里得算法(也叫辗转相除法)
引理:两个整数的最大公约数等于其中较小的那个数和两数相除余数的最大公约数。最大公约数(Greatest Common Divisor)缩写为GCD。
1 int gcd(int a, int b) 2 { 3 return b ? gcd(b, a % b) : a; 4 }