牛客多校第三场

H.Diff-prime Pairs

题意:给一个数n,求1~n有多少对数满足  和  都是质数,当 i1 ≠ i2 or j1 ≠ j2时(i1, j1) 和 (i2, j2)看做不同的一对数。

题解:首先,两个质数的最大公约数是1,那么除以1以后是自己本身依然也是一个质数,所以任意两个质数之间都是满足要求的,这里得到了第一部分答案,假设1~n有num个质数,ans1=C( num,2)。那么除了质数两两组合,要求除以最大公约数以后都是质数,那是不是可以理解为,相当于两个质数乘以相同的大于1的数以后,它们的最大公约数就是乘的这个数,除去以后还是它们自己也就是质数。所以对于每一个质数x来说,只用看它最多能乘多少而不超过n,这个数记为num1, num1=n/x;在它之前的质数比它小,同时乘以这个数一定不会超过n,所以我们枚举每个质数,看它前面有多少个其它的质数和它最多和其它质数一起乘几(乘1相当于本身,所以不算答案),设当前质数x前有num2个质数,于是得到ans2 =num2*(num1-1);

最后的答案 ans=(ans1+ans2)*2;(预处理就是需要开两个数组处理出1到每个数有多少个质数和第i个质数是谁)

附上代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e7 + 1e5;
int prime[maxn],sum[maxn];
bool vis[maxn];
int tot;
void init()
{
    for(int i=2;i<maxn;i++){
        if(vis[i]) continue;
        prime[tot++]=i;
        for(int j=i+i;j<maxn;j+=i){
            vis[j]=true;
        }
    }
    for(int i=2;i<maxn;i++) sum[i]=sum[i-1]+(vis[i]==false);
}
int main() {
    //freopen("in.txt","w",stdin);
    //freopen("out.txt", "w", stdout);
    init();
    int n;
    while(cin>>n){
        long long ans=0;
        ans+=(1LL*sum[n]*(sum[n]-1LL))/2;
        for(int i=0;prime[i]<=n;++i){
            long long temp=n/prime[i];
            ans+=1LL*i*(temp-1);
        }
        cout<<ans*2<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/wookaikaiko/article/details/81227315