• 牛客第三场多校 H Diff-prime Pairs


    链接:https://www.nowcoder.com/acm/contest/141/H
    来源:牛客网

    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 ≤ 10

    7

    输出描述:

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

    示例1

    输入

    3

    输出

    2
    示例2

    输入

    5

    输出

    复制
    6

    题意:输入一个n,n里面选一对数,满足 这两个式子的数都是素数,不同顺序也算是另一对

    思路:我们会发现i,j都是素数的话,那么最大公约数为1,那么肯定是一对,然后我们再想想(6,10),(6,9)...都是
    那么他们有什么规律呢,就是我们要使除了两个数的最大公约数之后都是素数,那么说明两个数分解之后就应该是 a=(素数)x*n b=(素数)y*n
    n是最大公约数那么其他的满足这个条件对数其实就是一个素数对,同时乘以一个数那么也是,例如(2,3)那么(4,6)(6,9)(8,12)都是
    满足条件的数,那么我们应该怎么计算呢,下面我们讲个例子

    首先想10以内有几个3的倍数呢,10/3=3个,这是常识
    那么我们就来计算,由所有的素数对扩展
    10以内的所有对,因为我们首先应该找出素数对,所以我们应该是遍历所有的素数,
    第一个 2 :10/2=5,10以内有5个2的倍数,我们再看2的前面有没有素数,没有,不计算
    第二个 3 :10/3=3 ....3 6 9,前面有素数2,我们就可以找到素数2组成(2,3),然后两个数同时乘以2,3,因为前面的
    小,所以我们始终能在6 9 前面找到4 6组成(4,6)(6,9)
    第三个:5...
    第四个:7...
     下面看代码实现
    #include<bits/stdc++.h>
    #define fi first
    #define ll  long long
    #define pll pair<int,int>
    #define se second
    #define mod 1000000007
    using namespace std;
    const int maxn = 10000010;
    bool isPrime[maxn];
    ll prime[maxn];
    ll sum[maxn];
    ll add[maxn];
    ll total=0;
    map< pll ,int> mp;
    void makePrime2()//筛法找出所有的素数
    {
        memset(isPrime,true,sizeof(isPrime));
        memset(prime,0,sizeof(prime));
        sum[1]=0;
        for(int i=2; i<maxn; i++)
        {
            if(isPrime[i])
            {
                prime[total++]=i;
                sum[i]=sum[i-1]+1;//用于存当前位置有多少个素数
            }
            else sum[i]=sum[i-1];
            for(int j=0; j<total && i*prime[j]<maxn; j++)
            {
                isPrime[i*prime[j]]=false;
                if(i%prime[j]==0) break;
            }
        }
    }
    int main()
    {
        makePrime2();
        ll n;
        scanf("%lld",&n);
        ll ans=0;
        for(int i=0; i<total&&prime[i]<=n; i++)
        {
             int p=n/prime[i];//找出n以内有多少个素数prime[i]的倍数
             ans+=(sum[prime[i]]-1)*p;//-1因为本身这个素数不算,然后和前面的素数进行匹配与扩展
        }
        printf("%lld
    ",ans*2);
    }
  • 相关阅读:
    Docker容器Centos容器安装openssh
    DEVOPS技术实践_15:使用Docker作为Jenkins的slave
    DEVOPS技术实践_14:使用docker部署jenkins
    oracle数据库创建实例
    Java 覆写初探
    Java super和this小结
    Java 继承学习
    Java 数据表映射
    Java 单向链表学习
    Java 继承初探
  • 原文地址:https://www.cnblogs.com/Lis-/p/9374618.html
Copyright © 2020-2023  润新知