题目链接

输入t对数 a, b 

求(b,a]内的每个数拆成素因子的个数和

这里每个数都可以写成素数的乘积,可以写成几个素数的和就有几个素因子,这里求的是(b,a]内的素因子和

思路:

素数的素因子个数是1

对于非素数A的素因子个数 = A/k  + 1 其中k是素数,也是第一个素数,或者K是比A小的数,并且A%k==0

 

下面是利用K是比A小的数,并且A%k==0

 1     void solve(){
 2         Scanner sc = new Scanner(System.in);
 3         int t = sc.nextInt();
 4         int a ,b;
 5         int MAX = 5000000;
 6         int[] arr=new int[MAX+1];
 7         for(int i=2;i<=MAX;i++){
 8             if(i%2==0){
 9                 arr[i] = arr[i/2]+1;
10                 continue;
11             }
12             for(int j=3;j*j<=i;j+=2){
13                 int k=i/j;
14                 if(k*j==i){
15                     arr[i] = arr[k] + 1;
16                     break;
17                 }
18             }
19             if (arr[i]==0)
20                 arr[i] = 1;
21         }
22         for(int i=2;i<=MAX;i++)
23             arr[i]+=arr[i-1];
24         while(t!=0){        
25         a = sc.nextInt();
26         b = sc.nextInt();
27         System.out.println(arr[a]-arr[b]);
28         t--;
29         }
30     }
View Code

这个读数据效率低,造成运行时间超时

这个是利用素数的,找到第一个素数K,并且A%k==0

    void solve3() throws NumberFormatException, IOException{
        int limit = 5000005;
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        int t=Integer.parseInt(br.readLine());
        StringTokenizer st;
        int div[] = new int[limit];
        boolean isPrime[] = new boolean[limit];
        int prime[] = new int[limit];
        int p=0;
        for(int i=2;i<limit;i++){
            if(!isPrime[i])
                prime[p++]=i;
            for(int j=0;j<p &&i*prime[j]<limit;j++){
                isPrime[i*prime[j]] = true;
                if(i%prime[j]==0)
                    break;
            }
        }
        for(int i=2;i<limit;i++){
            int k = i;
            if(!isPrime[i]){
                div[i] = 1;
                continue;
            }
            for(int j=0;j<p;j++){
                if(k%prime[j]==0){
                    div[i] = div[k/prime[j]] + 1;
                    break;
                }
            }
        }
        for(int i=2;i<limit;i++)
            div[i] += div[i-1];
        StringBuilder sb=new StringBuilder();
        for(int i=0;i<t;i++){
            st=new StringTokenizer(br.readLine());
            int a=Integer.parseInt(st.nextToken());
            int b=Integer.parseInt(st.nextToken());
            sb.append(div[a]-div[b]);
            sb.append('\n');
        }
            System.out.print(sb);
    }
View Code

换了读数据的方式,成功通过,这里利用到,素数筛选法求出素数的集合

参考链接

还有下面一种,都是参考素数筛选法的求解

void solve2() throws NumberFormatException, IOException{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        int t=Integer.parseInt(br.readLine());
        StringTokenizer st;
        int limit = 5000000;
        boolean[] array = new boolean[limit+1];
        int div[] = new int[limit+1];
        for(int i=2;i<=limit;i++){
            if(array[i]) continue;
            for(int j=i;j<=limit;j+=i){
                array[j] = true;
                int k=j;
                int temp=0;
                while(k%i==0){
                    k/=i;
                    temp++;
                }
                div[j]+=temp;
                
            }
        }
        for(int i=1;i<=limit;i++)
            div[i]+=div[i-1];
        StringBuilder sb=new StringBuilder();
        for(int i=0;i<t;i++){
            st=new StringTokenizer(br.readLine());
            int a=Integer.parseInt(st.nextToken());
            int b=Integer.parseInt(st.nextToken());
            sb.append(div[a]-div[b]);
            sb.append('\n');
        }
            System.out.print(sb);
    }
View Code
全部程序如下
package codeforces;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class D546 {
    
    void run() throws NumberFormatException, IOException{
//        solve();// 超时
        solve3();
    }
    void solve3() throws NumberFormatException, IOException{
        int limit = 5000005;
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        int t=Integer.parseInt(br.readLine());
        StringTokenizer st;
        int div[] = new int[limit];
        boolean isPrime[] = new boolean[limit];
        int prime[] = new int[limit];
        int p=0;
        for(int i=2;i<limit;i++){
            if(!isPrime[i])
                prime[p++]=i;
            for(int j=0;j<p &&i*prime[j]<limit;j++){
                isPrime[i*prime[j]] = true;
                if(i%prime[j]==0)
                    break;
            }
        }
        for(int i=2;i<limit;i++){
            int k = i;
            if(!isPrime[i]){
                div[i] = 1;
                continue;
            }
            for(int j=0;j<p;j++){
                if(k%prime[j]==0){
                    div[i] = div[k/prime[j]] + 1;
                    break;
                }
            }
        }
        for(int i=2;i<limit;i++)
            div[i] += div[i-1];
        StringBuilder sb=new StringBuilder();
        for(int i=0;i<t;i++){
            st=new StringTokenizer(br.readLine());
            int a=Integer.parseInt(st.nextToken());
            int b=Integer.parseInt(st.nextToken());
            sb.append(div[a]-div[b]);
            sb.append('\n');
        }
            System.out.print(sb);
    }

    void solve2() throws NumberFormatException, IOException{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        int t=Integer.parseInt(br.readLine());
        StringTokenizer st;
        int limit = 5000000;
        boolean[] array = new boolean[limit+1];
        int div[] = new int[limit+1];
        for(int i=2;i<=limit;i++){
            if(array[i]) continue;
            for(int j=i;j<=limit;j+=i){
                array[j] = true;
                int k=j;
                int temp=0;
                while(k%i==0){
                    k/=i;
                    temp++;
                }
                div[j]+=temp;
                
            }
        }
        for(int i=1;i<=limit;i++)
            div[i]+=div[i-1];
        StringBuilder sb=new StringBuilder();
        for(int i=0;i<t;i++){
            st=new StringTokenizer(br.readLine());
            int a=Integer.parseInt(st.nextToken());
            int b=Integer.parseInt(st.nextToken());
            sb.append(div[a]-div[b]);
            sb.append('\n');
        }
            System.out.print(sb);
    }

    void solve(){
        Scanner sc = new Scanner(System.in);
        int t = sc.nextInt();
        int a ,b;
        int MAX = 5000000;
        int[] arr=new int[MAX+1];
        for(int i=2;i<=MAX;i++){
            if(i%2==0){
                arr[i] = arr[i/2]+1;
                continue;
            }
            for(int j=3;j*j<=i;j+=2){
                int k=i/j;
                if(k*j==i){
                    arr[i] = arr[k] + 1;
                    break;
                }
            }
            if (arr[i]==0)
                arr[i] = 1;
        }
        for(int i=2;i<=MAX;i++)
            arr[i]+=arr[i-1];
        while(t!=0){        
        a = sc.nextInt();
        b = sc.nextInt();
        System.out.println(arr[a]-arr[b]);
        t--;
        }
    }

    
    
    public static void main(String[] args) throws NumberFormatException, IOException {
        
        new D546().run();

    }

}
View Code