JZOJ4919. 神炎皇

题目大意

给定 n 求有多少个数对 (a,b) 满足 a+bn (a+b) ab 的因子。

Data Constraint
n1014

题解

显然要求 aba+b 是一个整数。
先提出一个公因数 d ,得

daba+b

(a,a+b)=1,(b,a+b)=1

(ab,a+b)=1

所以要求 d a+b 的倍数。
k=a+b
d 可写为 d=k×c 的形式。
k×dn
cnk2
所以 d 的取值有 nk2
ab 的取值有 ϕ(k) 个。
枚举 k 然后统计即可。

时间复杂度: O(n)

SRC

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std ;

#define N 10000000 + 10
typedef long long ll ;

bool flag[N] ;
int Pri[N] , Phi[N] ;
ll n , ans ;

void Pre() {
    Phi[1] = 1 ;
    for (int i = 2 ; i < N ; i ++ ) {
        if ( !flag[i] ) {
            Pri[++Pri[0]] = i ;
            Phi[i] = i - 1 ;
        }
        for (int j = 1 ; j <= Pri[0] ; j ++ ) {
            if ( (ll)i * Pri[j] >= N ) break ;
            flag[i*Pri[j]] = 1 ;
            if ( i % Pri[j] == 0 ) { Phi[i*Pri[j]] = Phi[i] * Pri[j] ; break ; }
            Phi[i*Pri[j]] = Phi[i] * Phi[Pri[j]] ;
        }
    }
}

int main() {
    freopen( "uria.in" , "r" , stdin ) ;
    freopen( "uria.out" , "w" , stdout ) ;
    Pre() ;
    scanf( "%lld" , &n ) ;
    ll UP = sqrt(n) ;
    for (ll k = 2 ; k <= UP ; k ++ ) ans += n / (k * k) * Phi[k] ;
    printf( "%lld\n" , ans ) ;
    return 0 ;
}

以上.

你可能感兴趣的:(JZOJ4919. 神炎皇)