1. 程式人生 > >牛客第三場多校 H Diff-prime Pairs

牛客第三場多校 H Diff-prime Pairs

clipboard other 什麽 blank pri isp 分解 question adf

鏈接: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\n",ans*2);
}

牛客第三場多校 H Diff-prime Pairs