zoukankan      html  css  js  c++  java
  • (第三场) H Diff-prime Pairs 【数论-素数线性筛法+YY】

    题目链接

    题目描述 

    Eddy has solved lots of problem involving calculating the number of coprime pairs within some range. This problem can be solved with inclusion-exclusion method. Eddy has implemented it lots of times. Someday, when he encounters another coprime pairs problem, he comes up with diff-prime pairs problem. diff-prime pairs problem is that given N, you need to find the number of pairs (i, j), where  and  are both prime and i ,j ≤ N. gcd(i, j) is the greatest common divisor of i and j. Prime is an integer greater than 1 and has only 2 positive divisors.

    Eddy tried to solve it with inclusion-exclusion method but failed. Please help Eddy to solve this problem.

    Note that pair (i1, j1) and pair (i2, j2) are considered different if i1 ≠ i2 or j1 ≠ j2.

    输入描述:

    Input has only one line containing a positive integer N.

    1 ≤ N ≤ 107

    输出描述:

    Output one line containing a non-negative integer indicating the number of diff-prime pairs (i,j) where i, j ≤ N

    case 1

    input: 

    3

    output:

    2

    case 2

    input:

    5

    output:

    6

    题目大意:求 1~N 内满足 i / gcd(i, j) , j / gcd(i, j) 的有序对 i,j 的个数。

    思路:

    官方题解:

    Main Idea: Math, Prime Sieve, Prefix Sum

    If gcd(i_1, j_1) is not equal to gcd(i_2, j_2), (i_1, j_1) won’t be equal to (i_2, j_2).
    The answer will be sum of number of diff-prime pairs whose gcd is g for each g.

    Iterate each g, and find two distinct prime p_1, p_2. Then, (g p_1, g p_2) will be an answer if g p_1 <= N and g p_2 <= N. It will be reduced to find the number of prime within (N/g). It can be done by prime sieve and prefix sum.
    Since p_1 not equal to p_2, it’s obvious that gcd(g p_1, g p_2)=g
    Overall Time complexity: O(N) Overall Space complexity: O(N)

    一开始暴力i, j,结果也很暴力直接超时,剪枝也没办法,O(N^2)肯定不用想了

    其实这道题的做法是暴力最大公因数 gcd(i, j), 而不是直接暴力i, j, 因为 (i_1, j_1) 和 (i_2, j_2) 不相同说明他们的公因数也不同。所以我们只需要枚举1~N内的公因数 g 再寻找公因数相同下在区间(2, N/g)素数对组合情况就可以了,可以预处理用埃氏筛法打素数表,至于素数对组合,根据排列组合 sum[N/g]*(sum[N/g]-1), sum为前缀和,可以线性预处理出来。所以整道题的算法都是线性的。

    AC code:

    ///2018年牛客暑假多校训练赛第三场 H
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define INF 0x3f3f3f3f
    using namespace std;
    
    const int MAXN = 1e7+10;
    
    bool is_prime[MAXN];
    int num[MAXN];
    int N;
    
    void sivev(int N)      ///素数表
    {
        int p = 0;
        for(int i = 0; i <= N; i++) is_prime[i] = true;
        is_prime[0] = is_prime[1] = 0;
        for(int i = 2; i <= N; i++)
        {
            if(is_prime[i])
            {
                num[i] = 1;
                for(int j = 2*i; j <= N; j+=i) is_prime[j] = 0;
            }
        }
    }
    
    int main()
    {
        scanf("%d", &N);
        sivev(N);
        for(int i = 1; i <= N; i++)
            num[i]+=num[i-1];
    
        long long int ans = 0;
        for(int g = 1; g <= N; g++)
        {
            ans+=num[N/g]*(num[N/g]-1);
        }
    
        printf("%lld
    ", ans);
    
        return 0;
    }
  • 相关阅读:
    nodejs 获取客户端 ip 地址
    如何使用 nvm-windows 管理 nodejs 版本
    redis 环境搭建
    利用 ssh 传输文件
    如何在 Centos7 中安装 gcc
    如何在 Centos7 中安装 nginx
    django迁移model到别的app中
    ssl生成证书
    pip安装mysql报错 ld: library not found for -lssl
    mac重置蓝牙模块
  • 原文地址:https://www.cnblogs.com/ymzjj/p/9377906.html
Copyright © 2011-2022 走看看