码迷,mamicode.com
首页 > 其他好文 > 详细

开坑,填坑——莫比乌斯反演

时间:2015-09-18 20:30:40      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:

hdu 1695

题目:给出x和y的范围,要求gcd(x,y)==k的数对个数。

思路:首先把范围除k,然后就是求gcd(x,y)=1的数对个数。具体莫比乌斯公式的用法还不是很懂,目前的理解是这样的:

莫比乌斯公式给出了一个从和函数反演到原函数的方法。对于一个定义在正整数上的函数,其和函数F(n)定义为所有f(d)|d是n的因子的和。然后根据莫比乌斯公式,可由F求得f。

但是此题的形式有点不同。设f(k)表示gcd(x,y)=k的数对的个数。然后设F(k)表示gcd(x,y)=k的倍数的数对的个数。然后F是f的和函数,但是形式变成了这样:F(n)定义为所有f(d)|d是n的倍数的和。此时应用莫比乌斯函数的形式不变。

技术分享
/*
* @author:  Cwind
*/
//#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <map>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <set>
#include <cmath>
using namespace std;
#define IOS std::ios::sync_with_stdio (false);std::cin.tie(0)
#define pb push_back
#define PB pop_back
#define bk back()
#define fs first
#define se second
#define sq(x) (x)*(x)
#define eps (1e-3)
#define IINF (1<<29)
#define LINF (1ll<<59)
#define INF 1000000000
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> P;

zconst int MAXN = 1000000;
bool check[MAXN+10];
int prime[MAXN+10];
int mu[MAXN+10];
void Moblus(){
    memset(check,false,sizeof(check));
    mu[1] = 1;
    int tot = 0;
    for(int i = 2; i <= MAXN; i++){
        if( !check[i] ){
            prime[tot++] = i;
            mu[i] = -1;
        }
        for(int j = 0; j < tot; j++){
            if(i * prime[j] > MAXN) break;
            check[i * prime[j]] = true;
            if( i % prime[j] == 0){
                mu[i * prime[j]] = 0;
                break;
            }
            else{
                mu[i * prime[j]] = -mu[i];
            }
        }
    }
}

int a,b,c,d,k;
int T;
int cas=0;
int main(){
    freopen("/home/files/CppFiles/in","r",stdin);
    //freopen("defense.in","r",stdin);
    //freopen("defense.out","w",stdout);
    cin>>T;
    Moblus();
    while(T--){
        cin>>a>>b>>c>>d>>k;
        if(k==0){
            printf("Case %d: 0\n",++cas);
            continue;
        }
        ll ans1=0,ans2=0;
        if(b>d) swap(b,d);
        b/=k,d/=k;
        for(int i=1;i<=b;i++){
            ans1+=mu[i]*(ll)(b/i)*(d/i);
        }
        for(int i=1;i<=b;i++){
            ans2+=mu[i]*(ll)(b/i)*(b/i);
        }
        printf("Case %d: %lld\n",++cas,ans1-ans2/2);
    }
    return 0;
}
View Code

 

开坑,填坑——莫比乌斯反演

标签:

原文地址:http://www.cnblogs.com/Cw-trip/p/4820191.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!