bzoj 2818 Gcd

2818: Gcd

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 7381  Solved: 3281
[Submit][Status][Discuss]

Description

给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的
数对(x,y)有多少对.

Input

一个整数N

Output

如题

Sample Input

4

Sample Output

4

HINT

hint

对于样例(2,2),(2,4),(3,3),(4,2)


1<=N<=10^7

Source

总结:gcd(a, b) == c >>>>gcd(a / c, b / c) == 1;
然后想到枚举每个质数c,对欧拉函数求前缀和,
计数时要乘以2还要减去重复部分
两种情况:a / c > b / c, or a / c < b / c;
重复部分: a / c == b / c(应该减去)
 
#include<bits/stdc++.h>

using namespace std;

#define ll long long
const int maxn = 1e7 + 5;
int n, pri[maxn];
ll f[maxn];
bool Notpri[maxn]; int tot = 0;

void pre(int x) {
	f[1] = 1;
	for (int i = 2; i <= n; ++i) {
		if(!Notpri[i]) pri[++tot] = i, f[i] = i - 1;
		for (int j = 1; j <= tot && i * pri[j] <= n; ++j) {
			Notpri[i * pri[j]] = true;
			if(i % pri[j] == 0) {
				f[i * pri[j]] = f[i] * pri[j];
				break;
			} f[i * pri[j]] = f[i] * (pri[j] - 1);
		}
	}
	for (int i = 1; i <= n; ++i) f[i] += f[i - 1];
}

int main() {
	scanf("%d", &n);
	pre(n);
	ll ans = 0;
	for (int i = 1; i <= tot; ++i) {
		ans += f[n / pri[i]] * 2; ans--;
	} printf("%lld\n", ans);
	return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/oi-forever/p/8975661.html