约数
试除法求所有约数
- C++
vector<int> get_divisors(int x)
{
vector<int> res;
for (int i = 1; i <= x / i; i ++ )
if (x % i == 0)
{
res.push_back(i);
if (i != x / i) res.push_back(x / i);
}
sort(res.begin(), res.end());
return res;
}
- Java
public static TreeSet<Integer> get_divisors(int x) {
TreeSet<Integer> res = new TreeSet<>();
for (int i = 1; i <= x / i; i++) {
if (x % i == 0) {
res.add(i);
res.add(x / i);
}
}
return res;
}
约数个数与约数之和
- 如果 N = p
1^c1^ * p2^c2^ * ... * pk^ck^- 约数个数: (c
1+ 1) * (c2+ 1) * ... * (ck+ 1) - 约数之和: (p
1^0^ + p1^1^ + ... + p1^c1^) * ... * (pk^0^ + pk^1^ + ... + pk^ck^)
- 约数个数: (c
求最大公约数(欧几里得算法/辗转相除法)
-
核心:
(a, b) = (a, (a mod b)) -
C++
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
练习
01 试除法求约数
- 题目
- 题解
import java.io.*;
import java.util.*;
public class Main {
public static int n;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
n = Integer.parseInt(br.readLine());
while (n-- > 0) {
int x = Integer.parseInt(br.readLine());
TreeSet<Integer> res = get_divisors(x);
res.forEach(o -> pw.print(o + " "));
pw.println();
}
pw.close();
br.close();
}
public static TreeSet<Integer> get_divisors(int x) {
TreeSet<Integer> res = new TreeSet<>();
for (int i = 1; i <= x / i; i++) {
if (x % i == 0) {
res.add(i);
res.add(x / i);
}
}
return res;
}
}
02 约数个数
- 题目
- 题解
import java.io.*;
import java.util.*;
public class Main {
public static final int mod = (int) 1e9 + 7;
public static int n;
//存输入的所有数的质数出现的个数
public static Map<Integer, Integer> primes = new HashMap<>();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
n = Integer.parseInt(br.readLine());
while (n-- > 0) {
int x = Integer.parseInt(br.readLine());
//试除法分解质因数
for (int i = 2; i <= x / i; i++) {
while (x % i == 0) {
//jdk8 新的方法 获取键对应的值 如果键不存在 返回预先设定的值
primes.put(i, primes.getOrDefault(i, 0) + 1);
x /= i;
}
}
if (x > 1) {
primes.put(x, primes.getOrDefault(x, 0) + 1);
}
}
long res = 1;
for (Integer o : primes.values()) {
res = res * (o + 1) % mod;
}
pw.println(res);
pw.close();
br.close();
}
}
03 约数之和
- 题目
- 题解
import java.io.*;
import java.util.*;
public class Main {
public static final int mod = (int) 1e9 + 7;
public static int n;
//存输入的所有数的质数出现的个数
public static Map<Integer, Integer> primes = new HashMap<>();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
n = Integer.parseInt(br.readLine());
while (n-- > 0) {
int x = Integer.parseInt(br.readLine());
//试除法分解质因数
for (int i = 2; i <= x / i; i++) {
while (x % i == 0) {
//jdk8 新的方法 获取键对应的值 如果键不存在 返回预先设定的值
primes.put(i, primes.getOrDefault(i, 0) + 1);
x /= i;
}
}
if (x > 1) {
primes.put(x, primes.getOrDefault(x, 0) + 1);
}
}
long res = 1;
//约数之和: (p~1~^0^ + p~1~^1^ + ... + p~1~^c1^) * ... * (p~k~^0^ + p~k~^1^ + ... + p~k~^ck^)
for (Integer a : primes.keySet()) {
//a指的是上面的p b指的是上面的c
int b = primes.get(a);
//t指的是每一个(p~k~^0^ + p~k~^1^ + ... + p~k~^ck^)
long t = 1;
while (b-- > 0) {
//秦九韶算法
t = (t * a + 1) % mod;
}
res = res * t % mod;
}
pw.println(res);
pw.close();
br.close();
}
}
04 最大公约数
- 题目
- 题解
import java.io.*;
import java.util.*;
public class Main {
public static int n;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
n = Integer.parseInt(br.readLine());
while (n-- > 0) {
String[] str = br.readLine().split(" ");
pw.println(gcd(Integer.parseInt(str[0]), Integer.parseInt(str[1])));
}
pw.close();
br.close();
}
public static int gcd(int a, int b) {
return b != 0 ? gcd(b, a % b) : a;
}
}