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


    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
    ",++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
    ",++cas,ans1-ans2/2);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    rsyslog日志服务器搭建
    使用原生js实现对table中的某个单元格进行编辑并提交后台修改数据
    使用vuex管理的状态数据在刷新页面后数据丢失的问题
    brew install mongodb
    brew安装与启动redis
    zsh设置代理
    DNS Rebinding漏洞原理
    防数据泄露_MySQL库和数据安全
    PHP代码审计_用==与===的区别
    MySQL提权 通过UDF
  • 原文地址:https://www.cnblogs.com/Cw-trip/p/4820191.html
Copyright © 2020-2023  润新知