• BZOJ3309 DZY Loves Math(莫比乌斯反演+线性筛)


      一通正常的莫比乌斯反演后,我们只需要求出g(n)=Σf(d)*μ(n/d)的前缀和就好了。

      考虑怎么求g(n)。当然是打表啊。设n=∏piai,n/d=∏pibi 。显然若存在bi>1则这个d没有贡献。考虑bi为0和1两种情况。如果只看ai最小的质因子的选取情况,会发现大部分情况下其是0还是1,对f的取值是没有影响的,但会使μ取反,于是就抵消为0。而特殊情况即为所有ai均相同,此时若所有bi都取1会使f减少。与一般情况比较可以得到此时g(n)=(-1)质因子个数+1

      然后就可以线性筛了。记录一下n去掉最小质因子后的数及最小质因子的幂次就可以了。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 10000010
    int T,prime[N],f[N],p[N],c[N],v[N],cnt=0;
    bool flag[N];
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj3309.in","r",stdin);
        freopen("bzoj3309.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        T=read();
        flag[1]=1;p[1]=1;c[1]=0;f[1]=0;
        for (int i=2;i<=N-10;i++)
        {
            if (!flag[i]) prime[++cnt]=i,p[i]=1,c[i]=1,f[i]=1;
            for (int j=1;j<=cnt&&prime[j]*i<=N-10;j++)
            {
                int t=prime[j]*i;
                flag[t]=1;
                if (i%prime[j]==0)
                {
                    p[t]=p[i];
                    c[t]=c[i]+1;
                    if (c[p[i]]==0) f[t]=1;
                    else f[t]=(c[t]==c[p[i]]?-f[p[i]]:0);
                    break;
                }
                p[t]=i;
                c[t]=1;
                if (c[i]==0) f[t]=1;
                else f[t]=(c[i]==1?-f[i]:0);
            }
        }
        for (int i=1;i<=N-10;i++) f[i]+=f[i-1];
        while (T--)
        {
            int n=read(),m=read();
            long long ans=0;
            for (int i=1;i<=min(n,m);i++)
            {
                int t=min(n/(n/i),m/(m/i));
                ans+=1ll*(f[t]-f[i-1])*(n/i)*(m/i);
                i=t;
            }
            printf(LL,ans);
        }
        return 0;
    }
  • 相关阅读:
    链表总结
    源码,反码,补码,位运算
    JAVA打印乘法口诀表
    JAVA打印空三角形
    JAVA打印三角形
    列表,元组,字典,集合类型
    for 循环 ,数字类型,以及字符串类型
    基本运算符补充,流程控制if判断与while循环
    内存管理,数据类型的基本使用与基本运算符(python2中与用户交互)
    编程的分类,以及运行python解释器的原理,最后变量
  • 原文地址:https://www.cnblogs.com/Gloid/p/9683589.html
Copyright © 2020-2023  润新知