51nod 1222
求滿足 的二元組 的個數
設
則
/= , /=
枚舉一下
我們發現如果 就必須小於 了
此時的 代表
我們發現後面的問題就是求出有多少滿足 的三元組
我們設 ,這樣就可以枚舉出有序的所有三元組。
code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2000000;
bool is_prime[N];
int tot = 0, prime[N], mobius[N];
ll l, r, ans = 0;
inline void calc_mobius( int size )
{
memset( is_prime, true, sizeof( is_prime ) );
is_prime[1] = false; mobius[1] = 1;
for( int i = 2; i <= size; i ++ )
{
if( is_prime[i] )
prime[++tot] = i, mobius[i] = -1;
for( int j = 1; j <= tot; j ++ )
{
int p = prime[j];
if( i * p > size ) break;
is_prime[i*p] = false;
if( i % p == 0 )
{
mobius[i*p] = 0;
break;
}
mobius[i*p] = -mobius[i];
}
}
}
ll calc( ll n )
{
ll ret = 0;
for( ll k = 1; k*k <= n; k ++ )
{
if( !mobius[k] ) continue;
ll lim = n / ( k * k ), sum = 0;
for( ll d = 1; d*d*d <= lim; d ++ )
{
for( ll i = d+1; d*i*i <= lim; i ++ )
{
ll j = lim / ( i * d );
if( j < i ) continue;
sum += 2; // i == j
if( j < i + 1 ) continue;
sum += 3 * ( j - i );
}
ll tmp = lim / ( d * d );
if( tmp < d ) continue;
sum ++; // d == i == j
if( tmp - d < 1 ) continue;
sum += ( tmp - d ) * 2; // d == i
}
ret += mobius[k] * sum;
}
return ret;
}
int main()
{
calc_mobius( 1200000 );
scanf( "%lld%lld", &l, &r );
ans = calc( r );
ans -= calc( l - 1 );
printf( "%lld\n", ans );
return 0;
}