洛谷P2522
题目描述
t组询问,每组给出a, b, c, d, k五个数, 问 a <= x <= b, c <= y <= d,gcd(x, y) = k有多少组
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
const int N = 1e5 + 7 ;
ll miu[ N] , v[ N] ;
ll sum[ N] ;
void getmiu ( int n)
{
for ( int i = 1 ; i <= n; i++ )
v[ i] = 0 , miu[ i] = 1 ;
for ( int i = 2 ; i <= n; i++ )
{
if ( v[ i] )
continue ;
miu[ i] = - 1 ;
for ( int j = 2 * i; j <= n; j + = i)
{
v[ j] = 1 ;
if ( ( j / i) % i == 0 )
miu[ j] = 0 ;
else
miu[ j] * = - 1 ;
}
}
for ( int i = 1 ; i <= n; i++ )
sum[ i] = sum[ i - 1 ] + miu[ i] ;
}
ll solve ( ll x, ll y, ll d)
{
ll ans = 0 ;
ll l, r;
y / = d;
x / = d;
for ( l = 1 ; l <= min ( x, y) ; l = r + 1 )
{
r = min ( x / ( x / l) , y / ( y / l) ) ;
ans = ans + ( ( sum[ r] - sum[ l - 1 ] ) * ( x / l) * ( y / l) ) ;
}
return ans;
}
int main ( )
{
int t;
scanf ( "%d" , & t) ;
getmiu ( 50000 ) ;
while ( t-- )
{
ll a, b, c, d, k;
scanf ( "%lld %lld %lld %lld %lld" , & a, & b, & c, & d, & k) ;
ll ans = solve ( b, d, k) - solve ( a - 1 , d, k) - solve ( b, c - 1 , k) + solve ( a - 1 , c - 1 , k) ;
printf ( "%lld\n" , ans) ;
}
return 0 ;
}