(Solution:)
莫比乌斯反演+整除分块
懒得写式子了(QwQ)((Markdown)好难修。。。)
(Code:)
#include<bits/stdc++.h>
using namespace std;
namespace my_std
{
typedef long long ll;
#define fr(i,x,y) for(ll i=(x);i<=(y);i++)
#define pfr(i,x,y) for(ll i=(y);i>=(x);i--)
#define pf printf
inline ll read()
{
ll sum=0,f=1;
char ch=0;
while(!isdigit(ch))
{
if(ch=='-') f=-1;
ch=getchar();
}
while(isdigit(ch))
{
sum=(sum<<1)+(sum<<3)+(ch^48);
ch=getchar();
}
return sum*f;
}
inline void write(ll x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9) write(x/10);
putchar(x%10+'0');
}
}
using namespace my_std;
const ll N=5e4+50,hahaha=50000;
ll miu[N],sum[N],pri[N],mark[N],tot;
inline void cal_miu()
{
miu[1]=1;
for(ll i=2;i<=hahaha;i++)
{
if(!mark[i])pri[++tot]=i,miu[i]=-1;
for(ll j=1;j<=tot&&i*pri[j]<=hahaha;j++)
{
mark[i*pri[j]]=1;
if(i%pri[j]==0){miu[i*pri[j]]=0;break;}
else miu[i*pri[j]]=-miu[i];
}
}
for(ll i=1;i<=hahaha;i++)
{
sum[i]=sum[i-1]+miu[i];
}
}
inline ll solve(ll n,ll m)
{
if(n>m)swap(n,m);
ll ans=0,pos;
for(ll i=1;i<=n;i=pos+1)
{
pos=min(n/(n/i),m/(m/i));
ans+=(sum[pos]-sum[i-1])*(n/i)*(m/i);
}
return ans;
}
int main(void)
{
cal_miu();
ll qwq=read();
while(qwq--)
{
ll a=read(),b=read(),d=read();
write(solve(a/d,b/d));
putchar('
');
}
return 0;
}