hdu_1695: GCD 【莫比乌斯反演】

题目链接

这题求[1,n],[1,m]gcd为k的对数。而且没有顺序。

设F(n)为公约数为n的组数个数 
f(n)为最大公约数为n的组数个数

然后在纸上手动验一下F(n)和f(n)的关系,直接套公式就好了。注意要删去重复的。

关于 莫比乌斯反演 的结论

ACdreamers大神的相关博客  莫比乌斯反演   莫比乌斯反演与最大公约数

#include<bits/stdc++.h>
using namespace std;
typedef long long LL; const int maxn=1e6; int prime[maxn+];
bool check[maxn+];
int mu[maxn+]; void init()
{
mu[]=;
int tot=;
for(int i=;i<=maxn;i++)
{
if(!check[i])
{
prime[tot++]=i;
mu[i]=-;
}
for(int j=;j<tot;j++)
{
if(i*prime[j]>maxn) break;
check[i*prime[j]]=true;
if(i%prime[j]==)
{
mu[i*prime[j]]=;
break;
}
else
{
mu[i*prime[j]]=-mu[i];
}
}
}
} int main()
{
int T;
int a,b,c,d,k;
init();
scanf("%d",&T);
for(int kase=;kase<=T;kase++)
{
scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
if(k==)
{
printf("Case %d: 0\n",kase);
continue;
}
b/=k;
d/=k;
if(b>d) swap(b,d);
LL ans=;
for(int i=;i<=b;i++)
ans+=(LL)mu[i]*(b/i)*(d/i);
LL t=;
for(int i=;i<=b;i++)
t+=(LL)mu[i]*(b/i)*(b/i);
ans-=t/;
printf("Case %d: %I64d\n",kase,ans);
}
}
上一篇:POJ 1988 Cube Stacking(带权并查集)


下一篇:Hadoop2.2.0分布式安装配置详解[2/3]