BZOJ2818: Gcd 欧拉函数
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
Solution
看着黄学长的题解才弄懂这道题的QAQ,我数论真的好差啊...
求$gcd(x,y)=p$,p为素数的x,y取值有多少种
每个素数p对答案的贡献是$1$~$n/p$的有序互质对个数
我们可以设$y>=x$,显然当$x$确定的时候这个素数$p$的贡献就是$\phi(y)$
所以有序质数对的个数为$\sum_{i=1}^{i<=n/p}{\phi(i)}*2-1$
(有序质数对所以乘2,然后(1,1)在这里被算了2次所以-1)
#include <bits/stdc++.h> using namespace std ; #define ll long long const int N = 1e7+10 ; int n , tot ; int phi[ N ] , p[ N ] ; ll c[ N ] , ans ; bool v[ N ] ; void eular() { phi[ 1 ] = 1 ; for( int i = 2 ; i <= n ; i ++ ) { if( !v[ i ] ) { phi[ i ] = i - 1 ; p[ ++ tot ] = i ; } for( int j = 1 ; j <= tot ; j ++ ) { if( p[ j ] * i > n ) break ; v[ i * p[ j ] ] = 1 ; if( i % p[ j ] == 0 ) { phi[ i * p[ j ] ] = phi[ i ] * p[ j ] ; break ; } else phi[ i * p[ j ] ] = phi[ i ] * phi[ p[ j ] ] ; } } } int main() { scanf( "%d" , &n ) ; eular() ; for( int i = 1 ; i <= n ; i ++ ) c[ i ] = c[ i - 1 ] + phi[ i ] ; for( int i = 1 ; i <= tot ; i ++ ) { ans += c[ n / p[ i ] ] * 2 - 1 ; } printf( "%lld\n" , ans ) ; }