BZOJ 2818: Gcd( 欧拉函数 )

要求gcd(x, y) = p (1 <= x, y <= n, p为质数 ) 的数对(x, y)个数.我们枚举素数p, 令x' = x / p, y' = y / p, 则只须求  f(p) = gcd(x', y') = 1的数对(x', y')个数(1 <= x', y' <= n / p), 显然f(p) = (∑ phi(x')) * 2 - 1(1 <= x' <= n / p). 所以最后答案为 ∑f(p) 

-------------------------------------------------------------------

#include<bits/stdc++.h>
 
#define clr(x, c) memset(x, c, sizeof(x))
#define rep(i, n) for(int i = 0; i < n; ++i)
#define foreach(i, x) for(__typeof(x.begin()) i = x.begin(); i != x.end(); i++)
 
using namespace std;
 
typedef long long ll;
 
const int maxn = 10000009;
 
int prime[maxn], N = 0, n;
ll phi[maxn], ans = 0;
bool check[maxn];
 
void init() {
clr(check, 0);
phi[1] = 1;
for(int i = 2; i <= n; i++) {
if(!check[i]) {
prime[N++] = i;
phi[i] = i - 1;
}
for(int j = 0; j < N && prime[j] * i <= n; j++) {
check[prime[j] * i] = true;
if(i % prime[j])
   phi[i * prime[j]] = phi[i] * (prime[j] - 1);
else {
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
}
}
}
 
int main() {
freopen("test.in", "r", stdin);
cin >> n;
init();
for(int i = 2; i <= n; i++)
   phi[i] += phi[i - 1];
rep(i, N) ans += phi[n / prime[i]] * 2 - 1;
cout << ans << "\n";
return 0;
}

-------------------------------------------------------------------

2818: Gcd

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 2450  Solved: 1086
[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

 

posted @ 2015-07-28 12:39  JSZX11556  阅读(278)  评论(0编辑  收藏  举报