メビウス反転エントリーのタイトル
最後に、水問題大物口(I C A)
問題の意味:あなたの5つの数A、B、C、D 、K、 二つの数は、2つのセクションABおよびCDをxからGCD(x、y)はkに等しくなるように、Y、それぞれ採取したが、尋ねます((x、y)と(X、Y)と同じ)数の(x、y)は
、cは1つのプロセスである場合タイトルは特に顕著。
溶液は: - B 1 - 1ためのB / Kと1 - - 2つの数のそのGCDがまあをkに等しくなるように、Dが選択され、簡単に1に変換するD / Kの素数の数の、我々組F(t)は数の(x、y)は、T(x、y)に等しく、GCDに等しく、F(t)は(x、y)は、T(x、y)の複数を=番号GCDに等しく、描画することが容易ですF(N)=ΣF( D)(N | d)は、 第二メビウス反転式に従って我々は、Fを締結することができる(N)=Σ(MOB [D / N] * F [D]) (N | D)、そして私たちの以前の結論によると、私たちはライン上のF(1)を求めるためにここにいます。
慎重について、我々はFを見つけることができると思います(X)=(B / X)*(D / x)は、 コードを提供します。
//#pragma GCC optimize(3,"Ofast","inline")
//#include<unordered_map>
//#include<unordered_set>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<functional>
#include<cstring>
#include<string>
#include<cstdlib>
#include<queue>
#include<map>
#include<algorithm>
#include<set>
#include<stack>
#include<vector>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=1e5+10;
const ll mod=1e9+7;
ll prime[maxn],isprime[maxn];
ll mob[maxn];
ll num;
void getmobius()
{
memset(prime,0,sizeof(prime));
memset(mob,0,sizeof(mob));
memset(isprime,1,sizeof(isprime));
mob[1]=1;
for(int i=2;i<=100000;i++)
{
if(isprime[i])
{
prime[num++]=i;
mob[i]=-1;
}
for(int j=0;j<num&&i*prime[j]<=100000;j++)
{
isprime[i*prime[j]]=0;
if(i%prime[j]==0)
{
mob[i*prime[j]]=0;
break;
}
else mob[i*prime[j]]=-mob[i];
}
}
}
int main()
{
ll t;
getmobius();
scanf("%lld",&t);
ll a,b,c,d,k;
int K=0;
while(t--)
{
scanf("%lld%lld%lld%lld%lld",&a,&b,&c,&d,&k);
if(k==0)
{
printf("Case %d: 0\n",++K);
continue;
}
b/=k;d/=k;
ll ans1,ans2;
ans1=ans2=0;
for(ll i=1;i<=min(b,d);i++)ans1+=mob[i]*(b/i)*(d/i);//这里求的是所有的情况,但是(x,y)和(y,x)是一样的情况,所以这不是最终答案
for(ll i=1;i<=min(b,d);i++)ans2+=mob[i]*(min(b,d)/i)*(min(b,d)/i);//这里求的是1-b和1-d重叠部分的所有情况
ans1=ans1-ans2/2;//我们这样想,ans1代表的是所有情况,重叠部分可以说是都算了两次,非重叠部分很正常,只算了一次,然后我们讲ans1减去一个ans/2,就是减去一半的重叠部分,最后就是一个重叠部分和一个非重叠部分的最终答案了!(有点像容斥原理)
printf("Case %d: %lld\n",++K,ans1);
}
return 0;
}