• BZOJ 3309: DZY Loves Math


    BZOJ 3309: DZY Loves Math

    题目

    解法

    显然,这是一道莫比乌斯反演。
    因为a,b顺序与答案无关,所以我们强制(a<b)
    然后乱搞一波就会得到

    [ans=sum_{D=1}^{a}frac{a}{D}frac{b}{D}sum_{d|D}f(d)mu(frac{D}{d}) ]

    前面的套路大家都清楚,重要的是后面的那一部分怎么求。

    我们令(g(x)=sum_{d|x}f(d)mu(frac{x}{d}))
    (x),(d)分解质因数得到
    (x=P_1^{a_1}P_2^{a_2}...P_n^{a_n})
    (d=P_1^{b_1}P_2^{b_2}...P_n^{b_n})
    因为莫比乌斯函数(mu)的原因,我们的只有对于(forall i都有a_i-b_ileq 1)(f)对答案才有贡献。
    也就是说我们要从这(n)个不同的质因子中任选一部分使次数-1,得到(d),求(f(d))
    然后若(exists a_i<a),那么不论这一位选与不选(f(d)最终答案都与这一位无关),而对于莫比乌斯函数(mu)来说,这就是(1和-1)的区别,所以此时(g(x)=0),只有当所有(a_i=a)时,有一种特殊情况就是每个数都被选时会使(f(d)=a-1),不能与其他情况合并为0,所以它对答案的贡献是-1,再乘上莫比乌斯函数(mu),最终(g(x)=(-1)^{n+1})

    综上所述
    假设(x=P_1^{a_1}P_2^{a_2}...P_n^{a_n})
    若对于(forall i,j)都有(a_i=a_j)
    那么(g(x))=(-1)^{n+1}
    否则(g(x)=0)

    这样(g(x)就可以通过线性筛筛出来)
    而$$ans=sum_{D=1}^{a}frac{a}{D}frac{b}{D}g(D)$$
    所以答案就很好求了。

    完整代码

    #include<bits/stdc++.h>
    #define ll long long 
    using namespace std;
    const int _=1e7+20,M=1e7+1;
    int prime[_],f[_],low[_],num[_],isprime[_],s;
    void pre(){
        for(int i=2;i<=M;++i){
            if(!isprime[i])low[i]=num[i]=f[i]=1,prime[++s]=i;
            for(int j=1;j<=s&&i*prime[j]<=M;++j){
                int k=i*prime[j];
                isprime[k]=1;
                if(i%prime[j]){
                    low[k]=1;num[k]=i;
                    f[k]= low[k]==low[i]?-f[i]:0;
                }
                else {
                    low[k]=low[i]+1;num[k]=num[i];
                    if(num[k]==1)f[k]=1;
                    else f[k]=low[k]==low[num[k]]?-f[num[k]]:0;
                    break;
                }
            }
        }
        for(int i=1;i<=M;++i)
            f[i]+=f[i-1];
    }
    int main(){
        pre();
        int T;
        cin>>T;
        while(T--){
            int n,m;
            scanf("%d%d",&n,&m);
            if(n>m)swap(n,m);
            ll ans=0;
            for(int l=1,r;l<=n;l=r+1){
                r=min(m/(m/l),n/(n/l));
                ans+=1ll*(n/l)*(m/l)*(f[r]-f[l-1]);
            }
            printf("%lld
    ",ans);
        }
    }
    
  • 相关阅读:
    如何打开肉鸡的3389端口(xp的)
    XP鲜为人知的实用技巧(一)
    利用Ms08067工具进行溢出攻击
    教你建一个别人看不到打不开的文件夹
    在IE上显示自己的名字
    QQ使用的七大非常规秘籍
    第五篇:Python函数基础篇
    Centos7之Systemd(Service文件)详解
    Linux GCC make文件的写法3
    DSP/BIOS学习笔记——2.SWI
  • 原文地址:https://www.cnblogs.com/ljq-despair/p/8821906.html
Copyright © 2020-2023  润新知