链接:https://www.nowcoder.com/acm/contest/141/H
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
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示例1
输入
3输出
2示例2
输入
5输出
6
题目大意:
给出一个N,求出 i,j<=N中 i/gcd(i,j)和j/gcd(i,j)都是素数的ij的对数
题目分析:
如果i,j符合题目要求
我们把i和j拆分成
i=A*k1,j=A*k2,其中k1,k2为素数。
那么显然,如果A确定了的话,能使i和j在上述等式成立下的素数个数K也可以求出来,那么求一个组合数C(K,2)就是A在某一个值时i和j能求得的组数,这里求出的ij不可交换。
那么我们就可以通过枚举A然后对上述结果求和后*2就能得出答案了。
#include<iostream>
#include<string>
#include<cstring>
#include<vector>
#include<map>
#include<algorithm>
#include<queue>
#include<set>
#include<cstdio>
#include<functional>
#include<iomanip>
#include<cmath>
#include<stack>
#include<iomanip>
#include<functional>
#include<iomanip>
#include<bitset>
#define lson l,m
#define rson m+1,r
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
const int maxn = int(1e7) + 100;
const int BN = 30;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = (int)1e9 + 7;
const double eps = 1e-6;
bool vis[maxn];
vector<int>pri;
void init() {
memset(vis, 0, sizeof(vis));
pri.clear();
vis[0] = vis[1] = 1;
for (int i = 2; i < maxn; i++) {
if (!vis[i]) {
pri.push_back(i);
for (int j = i * 2; j < maxn; j += i)
vis[j] = 1;
}
}
}
int main() {
//freopen("test.in","r",stdin);
//ios::sync_with_stdio(false);
//cin.tie(0);
init();
int n;
while (~scanf("%d", &n)) {
LL ans = 0;
for (int i = 1, j = pri.size() - 1; i <= n; i++) {
while (j != -1 && LL(pri[j])*LL(i) > LL(n))
j--;
if (j == -1) break;
ans += LL(j)*(LL(j) + 1) / 2;
}
printf("%lld\n", ans * 2);
}
return 0;
}