Codeforces D546:Soldier and Number Game

题目链接:http://codeforces.com/problemset/problem/546/D

输入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     }

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

这个是利用素数的,找到第一个素数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);
    }

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

参考链接

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

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);
    }

全部程序如下

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();

    }

}

时间: 2024-10-22 10:24:13

Codeforces D546:Soldier and Number Game的相关文章

网络流(最大流) CodeForces 546E:Soldier and Traveling

In the country there are n cities and m bidirectional roads between them. Each city has an army. Army of the i-th city consists of ai soldiers. Now soldiers roam. After roaming each soldier has to either stay in his city or to go to the one of neighb

数学+DP Codeforces Round #304 (Div. 2) D. Soldier and Number Game

题目传送门 1 /* 2 题意:这题就是求b+1到a的因子个数和. 3 数学+DP:a[i]保存i的最小因子,dp[i] = dp[i/a[i]] +1;再来一个前缀和 4 */ 5 /************************************************ 6 Author :Running_Time 7 Created Time :2015-8-1 14:08:34 8 File Name :B.cpp 9 ******************************

DP+埃氏筛法 Codeforces Round #304 (Div. 2) D. Soldier and Number Game

题目传送门 1 /* 2 题意:b+1,b+2,...,a 所有数的素数个数和 3 DP+埃氏筛法:dp[i] 记录i的素数个数和,若i是素数,则为1:否则它可以从一个数乘以素数递推过来 4 最后改为i之前所有素数个数和,那么ans = dp[a] - dp[b]: 5 详细解释:http://blog.csdn.net/catglory/article/details/45932593 6 */ 7 #include <cstdio> 8 #include <algorithm>

CodeForces 1325E - Ehab&#39;s REAL Number Theory Problem【质因子+】

题意: ??给定一个数组 \(a\) ,数组中任意一个元素的因子数不超过 \(7\) ,找出一个最短的子序列,满足该子序列之积为完全平方数.输出其长度. 数据范围:\(1≤n≤10^5,1≤a_i≤10^6\) 分析: ??首先,对于数组中的每个元素,如果其因子中包含有一个完全平方数,那么可以把该完全平方数除去,不影响最后的结果. ??然后,可以发现,当一个数的因子个数 \(\leq 7\) 时,其包含的质因子个数 \(\leq 2\).(如果有3个质因子,那么至少有 \(8\) 个因子)当我们

Codeforces 449D:Jzzhu and Numbers

Codeforces 449D:Jzzhu and Numbers 题目链接:http://codeforces.com/problemset/status?friends=on 题目大意:给出$n$个数,求有多少种组合使得$a_{i_1}\&a_{i_2}\&...\&a_{i_k}=0(0 \leqslant i < n)$,答案对$10^9+7$取模. 容斥原理+DP 设位与$(\&)$后二进制表示中有$k$个$1$的组合数为$A_k$,则有, $A_0=$所有

Codeforces 757B:Bash&#39;s Big Day(分解因子+Hash)

http://codeforces.com/problemset/problem/757/B 题意:给出n个数,求一个最大的集合并且这个集合中的元素gcd的结果不等于1. 思路:一开始把素数表打出来,发现有9k+个数,不能暴力枚举.发现O(sqrt(n)*n)似乎可行,就枚举因子,然后出现过的因子就在Hash[]加1,最后枚举素数表里的元素,找出现次数最多的,因为那些数都可以映射在素数表里面.注意最少的ans是1. 1 #include <cstdio> 2 #include <algo

Codeforces 754E:Dasha and cyclic table

Codeforces 754E:Dasha and cyclic table 题目链接:http://codeforces.com/problemset/problem/754/E 题目大意:$A$矩阵($size(A)=n \times m$,仅含'a'-'z')在整个平面做周期延拓,问$B$矩阵($size(B)=r \times c$,包含'a'-'z'及'?','?'为通配符)在哪些位置能与$A$矩阵匹配.输出$n \times m$的01矩阵,1表示在该位置匹配. 枚举+bitset常

Codeforces 798D:Mike and distribution

Codeforces 798D:Mike and distributio 题目链接:http://codeforces.com/problemset/problem/798/D 题目大意:给出两个大小为$n$的数列$A,B$,现要求从这两个数列相同位置取出$K(K \leqslant n/2+1)$个数,使得$2 \times subA>sumA$且$2 \times subB>sumB$. 想法题 我们需要从数列$A$和数列$B$中取出$K$个数,使得这$K$个数的和比剩下$n-K$个数的和

javascript篇:javascript对象——Number

创建Number对象: var myNum = new Number(value); var myNum = Num(value); var myNum = value;//必要时会转换成Number对象,如myNum.toString()先转换,再调用. var myNum = Number.MAX_VALUE; Number对象的属性 Max_VALUE:可表示的最大的数 MIN_VALUE:可表示的最小的数 NaN:非数字值 NEGATIVE_INFINITY:负无穷大,溢出值 POSIT