You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.
# include <bits/stdc++.h>
using namespace std ;
typedef long long LL ;
const int N = 50010 ;
//线性筛法求莫比乌斯函数(枚举约数)
int mu [ N ] , sum [ N ] ; // 莫比乌斯函数的前缀和
int primes [ N ] , cnt ;
bool st [ N ] ;
void get_mobius ( LL n ) {
mu [ 1 ] = 1 ;
for ( int i = 2 ; i < = n ; i + + ) {
if ( ! st [ i ] ) {
primes [ cnt + + ] = i ;
mu [ i ] = - 1 ; //奇数个质因子, 现在只有1个质因子, 所以函数值是-1
}
for ( int j = 0 ; primes [ j ] * i < = n ; j + + ) {
int t = primes [ j ] * i ;
st [ t ] = true ; //把t筛掉
// t里有primes[j],而i里如果还有一个primes[j],那么最少有2个及以上的primes[j],根据mobius函数定义, 此时函数值为0
if ( i % primes [ j ] = = 0 ) {
mu [ t ] = 0 ;
break ;
}
mu [ t ] = - mu [ i ] ;
//因为执行到这里primes[j]这个质因子只有1个, 所以整个莫比乌斯函数里有没有某个质因子的个数大于1个, 取决于i的质因子个数
}
}
// 维护莫比乌斯函数前缀和
for ( int i = 1 ; i < = n ; i + + ) sum [ i ] = sum [ i - 1 ] + mu [ i ] ;
}
int main ( ) {
//筛法求莫比乌斯函数
get_mobius ( N - 1 ) ;
int T ;
cin > > T ;
while ( T - - ) {
int a , b , d ;
cin > > a > > b > > d ;
//套路啊, 满满的套路, 直接先用最大公约数a/gcd(a,b)=a',b/gcd(a,b)=b',映射到a',b'
a / = d , b / = d ;
// n为 min(a', b')
int n = min ( a , b ) ;
LL res = 0 ;
// l r, 是每一段的左右边界
// 每次只能取较小的那个上界作为这一段的右端点r
// 然后下次迭代时下一段的左端点就是r + 1
for ( int l = 1 , r ; l < = n ; l = r + 1 ) { //分块大法
r = min ( n , min ( a / ( a / l ) , b / ( b / l ) ) ) ;
res + = ( sum [ r ] - sum [ l - 1 ] ) * ( LL ) ( a / l ) * ( b / l ) ;
}
printf ( " %lld \n " , res ) ;
}
return 0 ;
}