①:+b≤N、+ bを満たすために求めて、Nの整数正の所与| * B、番号(A、B)の数は、N≤1e14あります。
我々集合D = GCD(A、B)。次に '* D、B = B' * D、容易に入手可能なGCD( 'B')== 1 =。
+ bを代入し、A = '* dおよびB = B' * D | * B、( '+ B')容易に入手| a'b'd。
もちろん我々は( '+ B') '割り切れる、その後、(' A'B + B「)ではありません持っている| D。
我々は* D = '+ B' = K、Kを設け、N、T * K = D、次いで∈K [2、SQRT(N)]。
その与えられたkについて、その正当なことの数?
(A '+ B')* D = K * K * T≤N、次にT≤N /(K * K)、kは定数、N個の範囲内、すなわちT K有効な範囲であることに留意されたいです。
与えられたkについて、その数の法的( 'B')の数は?kはなら= '+ B'、GCD( '+ B'「)= 1、次いで明らかANSのことφ(K)。
YR =(N / K * K)* φ(k)は、 k∈[2.sqrt(N)]、O(SQRT(N))
#include <iostreamの> する#include <CStringの> する#include <cstdioを> する#include <cmath> 使用して 名前空間をSTD。 #define E出口(0) の#define再登録 の#define LL長い長い CONST LL MAXN = 1E7 + 1 。 LL N、T、ANS。 int型のCNT、プライム[MAXN]、VIS [MAXN]、アドイン[MAXN]。 int型のmain() { scanf関数(" %のLLD "、&n)を。 LL T = SQRT(N)。 イン[ 1 ] = 1 。 以下のための(再int型私は= 2、iは<= T; ++ I){ 場合(!VIS [I]){ プライム[ ++ CNT] = I; イン[I] = I- 1 。 } ため(再INT J = 1 ; J <= CNT; ++ J){ 場合(i *が素数[J]> T)、 ブレーク。 VIS [私はプライム[jは*]] = 1 ; もし(I%プライム[j] == 0 ){ イン[私は ]プライム[Jを*] =イン[I] * プライム[J]。 ブレーク; } 他のアドイン[i *が、プライム[J] =イン[I] * アドイン[プライム[J]]; } } のための(再LL K = 2、K <= T; ++ K) ANS + =(LL)(N /(K * K))* (LL)イン[K]。 printf(" %のLLD " 、ANS)。 リターン 0 ; }