质数与约数目录
文章目录
一、质数
1、试除法求质数
模板
时间复杂度一定是O(sqrt(n))
boolean is_prime(int n ){
if(n < 2 ) return false;
for(int i = 2 ; i <= n /i ; i ++){
if(n % i == 0 ) return false;
}
return true ;
}
原题
代码
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
while(n-- > 0){
int m = scan.nextInt();
if(is_prime(m)) System.out.println("Yes");
else System.out.println("No");
}
}
static boolean is_prime(int n ){
if(n < 2 ) return false;
for(int i = 2 ; i <= n /i ; i ++){
if(n % i == 0 ) return false;
}
return true ;
}
}
2、分解质因数
模板
void divide(int n ){
for(int i = 2 ; i <= n /i ; i ++){
if(n % i == 0 ) {//i一定是质数 这大括号是求i的次数
int s = 0 ;
while(n % i == 0 ){
n /= i ;
s++;
}
System.out.println(i +" "+s);
}
}
//n当中最多只包含一个大于根号n的质数
//所以最后循环结束 加1就可以了
if(n > 1) System.out.println( n +" "+ 1);
System.out.println();
}
原题
代码
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
while(n-- > 0){
int m = scan.nextInt();
divide(m);
}
}
static void divide(int n ){
for(int i = 2 ; i <= n /i ; i ++){
if(n % i == 0 ) {
int s = 0 ;
while(n % i == 0 ){
n /= i ;
s++;
}
System.out.println(i +" "+s);
}
}
if(n > 1) System.out.println( n +" "+ 1);
System.out.println();
}
}
3、筛质数(线性筛法)
模板
n只会被最小质因子筛掉
p[]用来存放质数 st[]为质数则false
void get_p(int n ){//用的是线性筛法
for(int i = 2 ; i <= n ; i++){//循环所有数
if(!st[i]) p[cnt++] = i ;
for(int j = 0 ; p[j] <= n / i ; j++){
st[p[j]*i] = true;//
if(i % p[j] == 0) break ;
}
}
}
原题
代码
import java.util.Scanner;
public class Main{
static int cnt =0 ;
static int N = (int)1e6+10;
static boolean [] st = new boolean[N];
static int [] p = new int[N];
public static void main(String [] args){
Scanner san = new Scanner(System.in);
int n = san.nextInt();
get_p(n);
System.out.println(cnt);
}
static void get_p(int n ){//用的是线性筛法
for(int i = 2 ; i <= n ; i++){//循环所有数
if(!st[i]) p[cnt++] = i ;
for(int j = 0 ; p[j] <= n / i ; j++){
st[p[j]*i] = true;
if(i % p[j] == 0) break ;
}
}
}
}
二、约数
1.试除法求约数
模板
List<Integer> res = new ArrayList<>();
for(int i = 1 ; i <= n /i ; i++){
if(n % i == 0){
res.add(i);
//这里特判一下,因为约数有可能是两个约数相同,比如4*4,5*5,它本只有一个约数,所以就要特判一下
if(i != n / i) res.add(n/i);
}
}
Collections.sort(res);
原题
代码
import java.util.*;
public class Main{
public static void main(String [] args){
Scanner san = new Scanner(System.in);
int n = san.nextInt();
while(n-- > 0){
int m = san.nextInt();
disor(m);
}
}
public static void disor(int n ){
List<Integer> res = new ArrayList<>();
for(int i = 1 ; i <= n /i ; i++){
if(n % i == 0){
res.add(i);
//这里特判一下,因为约数有可能是两个约数相同,比如4*4,5*5,它本只有一个约数,所以就要特判一下
if(i != n / i) res.add(n/i);
}
}
Collections.sort(res);
for(int i : res){
System.out.print(i + " ");
}
System.out.println();
}
}
2.约数个数
模板
Map<Integer,Integer> map = new HashMap<>();
while(n-- > 0){
int m = san.nextInt();
for(int i = 2 ; i <= m / i ; i++){//分解质因数的模板
while(m % i == 0 ){
m /= i ;
map.put(i , map.getOrDefault(i , 0) + 1);
}
}
if(m > 1) map.put(m , map.getOrDefault(m , 0) + 1);
}
//求个数
long res = 1 ;
for(int key : map.values()){
res = res * (key + 1) % N ;
}
System.out.println(res);
原题
代码
import java.util.*;
public class Main{
static int N = (int)1e9 + 7;
public static void main(String [] args){
Scanner san = new Scanner(System.in);
int n = san.nextInt();
Map<Integer,Integer> map = new HashMap<>();
while(n-- > 0){
int m = san.nextInt();
for(int i = 2 ; i <= m / i ; i++){//分解质因数的模板
while(m % i == 0 ){
m /= i ;
map.put(i , map.getOrDefault(i , 0) + 1);
}
}
if(m > 1) map.put(m , map.getOrDefault(m , 0) + 1);
}
long res = 1 ;
for(int key : map.values()){
res = res * (key + 1) % N ;
}
System.out.println(res);
}
}
3、约数之和
模板
运用秦九韶算法
long res = 1 ;
for(int k : map.keySet()){
int a = map.get(k);
long t = 1 ;
while(a-- > 0){//执行指数a次
t = (k * t + 1) % N;//t乘底数
}
res = res * t % N ;
}
System.out.println(res);
原题
代码
import java.util.*;
public class Main{
static int N = (int)1e9 + 7;
public static void main(String [] args){
Scanner san = new Scanner(System.in);
int n = san.nextInt();
Map<Integer,Integer> map = new HashMap<>();
while(n-- > 0){
int m = san.nextInt();
for(int i = 2 ; i <= m / i ; i++){//分解质因数的模板
while(m % i == 0 ){
m /= i ;
map.put(i , map.getOrDefault(i , 0) + 1);
}
}
if(m > 1) map.put(m , map.getOrDefault(m , 0) + 1);
}
long res = 1 ;
for(int k : map.keySet()){
int a = map.get(k);
long t = 1 ;
while(a-- > 0){//执行指数a次
t = (k * t + 1) % N;//t乘底数
}
res = res * t % N ;
}
System.out.println(res);
}
}
4、最大公约数
模板
//欧几里得算法,也可以叫做辗转相除法
/** | 这个符号表示整除
- 基本性质: d|a -> d|b -> d|a+b -> d|ax+by
- 核心原理:最大公约数 (a,b) = (b,a%b)
public static int gcd(int a,int b){
return b != 0 ? gcd(b,a % b) : a;
}