hdu1695 GCD

转载请注明出处,谢谢http://blog.csdn.net/bigtiao097?viewmode=contents

题意

给定整数a,b,c,d,k,a=c=1求 axc,  byd(1c,d,k105) 且gcd(x,y)=k的数对(x,y)有多少对.

思路

这个题比bzoj2818 稍微复杂一点,可以看一下这里
由于a,b不相等,不能像bzoj2818一样用欧拉函数来做了
莫比乌斯反演轻松解决

g(n)=n|df(d)f(n)=n|dμ(dn)g(d)

f(n) 代表    gcd(x,y)=n   xy
g(n)gcd(x,y)%n=0  xy
这样就有了
g(n)=n|df(d)

然后利用反演公式,因为 g(n) 非常的好求, g(n)=cn×dn
根据上述的反演公式直接计算就可以了
还有一点就是这个题要求(x,y)和(y,x)视为相同的,所以需要去重,怎么去呢,其实很简单
我们在算完 axc,  byd ,再算一下 axmin(c,d),  bymin(c,d) ,然后减一下就行


具体代码如下:
Result:Accepted     Memory: 2268KB     Time : 31MS

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int maxn=1e5+5;
bool vis[maxn];
int prime[maxn];
int mu[maxn];
int n,a,b,c,d,k;
int tot;
ll ans1,ans2;
int Case;
void mobius()
{
    memset(vis,0,sizeof vis);
    mu[1] = 1;
    tot = 0;
    for(int i = 2; i <maxn; i++)
    {
        if( !vis[i] ){
            prime[tot++] = i;
            mu[i] = -1;
        }
        for(int j = 0; j < tot; j++)
        {
            if(i * prime[j] >=maxn) break;
            vis[i * prime[j]] = true;
            if( i % prime[j] == 0)
            {
                mu[i * prime[j]] = 0;
                break;
            }
            else
                mu[i * prime[j]] = -mu[i];
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    mobius();
    int T;
    cin>>T;
    while(T--)
    {
        ans1 = 0;
        ans2 = 0;
        cin>>a>>b>>c>>d>>k;
        cout<<"Case "<<++Case<<": ";
        if(k==0)
        {
            cout<<0<<endl;
            continue;
        }
        n = min(b,d);
        for(int x=k;x<=n;x+=k)
        {
            ans1+= 1LL*mu[x/k]*(b/x)*(d/x);
            ans2+= 1LL*mu[x/k]*(n/x)*(n/x);

        }
        ans2--;
        cout<<ans1-ans2/2<<endl;
    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值