hdu1695gcd(Mobius反演)

莫比乌斯反演的资料
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的个数
也就是求f
(1)=sigma(i<=min(b,d)) u(i)F(i)

还有另一种推法
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 <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include <iterator>
#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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值