莫比乌斯反演的资料
http://wenku.baidu.com/view/542961fdba0d4a7302763ad5.html
http://baike.baidu.com/link?url=1qQ-hkgOwDJAH4xyRcEQVoOTmHbiRCyZZ-hEJxRBQO8G0OurXNr6Rh6pYj9fhySI0MY2RKpcaSPV9X75mQv0hK
莫比乌斯反演的两种形式,书上一般只介绍第一种。
这道题用的是第二种。
f(k)是1<=x<=b,1<=y<=d中gcd(x,y)==k的个数
F(k)是1<=x<=b,1<=y<=d中gcd(x,y)是k的倍数的个数
F(k)=(b/k)*(d/k)。
并且这道题转化为
f(k) =f(1)是1<=x<=b/k,1<=y<=d/k中gcd(x,y)==1的个数
(1)=sigma(i<=min(b,d)) u(i)F(i)
也就是求f
还有另一种推法
Sigma(d|n) u(d)=(n==1)。
这道题就是相当于求
Sigma(1< =i< =x) Sigma(1< =j< =y) (gcd(i,j)==1)=
Sigma(1< =i< =x) Sigma(1< =j< =y)Sigma(d|gcd(i,j))u(d)=
Sigma(1< =i< =x) Sigma(1< =j< =y) Sigma(d|i且d|j)u(d)=
Sigma(d)u(d)*Sigma(1< =i< =x且d|i) Sigma(1< =j< =y且d|j)=
Sigma(d)u(d)* (x/i) *(y/i).
#include
#include
#include
#include
#include
#include
#include
#include
#define ms(X) memset(X,0,sizeof(X))
#define mcs(X) memset(X,-1,sizeof(X))
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
int mobius[100020];
void getMbs(void)
{
ms(mobius);
for(int i=1;i<=100000;i++)
{
int target=(i==1?1:0);
int delta=target-mobius[i];
mobius[i]=delta;
for(int j=(i<<1);j<=100000;j+=i)
mobius[j]+=delta;
}
}
int main()
{
int t,ti=0;
cin>>t;
getMbs();
while(++ti<=t)
{
int a,b,c,d,k;
scanf("%d %d %d %d %d",&a,&b,&c,&d,&k);
if(!k) {printf("Case %d: 0\n",ti);continue;}
b/=k,d/=k;
if(b>d){int tmp=b;b=d;d=tmp;}
LL res1=0,res2=0;
for(int i=1;i<=b;i++)
res1+=(LL)mobius[i]*(b/i)*(d/i);
for(int i=1;i<=b;i++)
res2+=(LL)mobius[i]*(b/i)*(b/i);
printf("Case %d: %I64d\n",ti,res1-res2/2);
}
return 0;
}