• 【莫比乌斯反演】专题总结


    为什么感觉我好像之前学过这玩意- -?

    莫比乌斯反演

    莫比乌斯反演就是一个能求gcd为多少的个数有几个的东西- -(反正我只知道这么用)

    f(x)表示gcd为x的倍数的个数

    g(x)表示gcd为x的个数

    莫比乌斯反演的基本形式是

    f(n) = Σ (g(d))   d | n
    g(n) = Σ (g(d) * miu (n / d))  d | n

    还有一种形式是

    f(n) = Σ (g(d))  n | d
    g(n) = Σ (f(d) * miu (d / n))  n | d

    其中miu(i)是莫比乌斯函数

    莫比乌斯函数

               1           (i==1)

    miu[i]=-1^k      (i为k个不同质数相乘)

              0            (其他情况)

    求莫比乌斯函数可以用线性筛法O(n)求出

    O(n)求莫比乌斯函数代码

     1 void makepri(){
     2     miu[1]=1;
     3     for (int i=2;i<N;i++){
     4         if (!bo[i]) pri[++pri[0]]=i,miu[i]=-1;
     5         for (int j=1;j<=pri[0] && i*pri[j]<N;j++){
     6             bo[i*pri[j]]=1;
     7             if (i%pri[j]==0){
     8                 miu[i*pri[j]]=0;
     9                 break;
    10             }else miu[i*pri[j]]=-miu[i];
    11         }
    12     }
    13 }

    优化

    用暴力for求g[i]的时间复杂度是O(n)的

    但是有的题目会给出很多询问 导致O(n)不能满足出题人- -

    假设题目要求gcd(x,y)=1的个数(1<=x<=n,1<=y<=m)

    那么f[i]=[n/i]*[m/i]

    我们发现[n/i]的值只有√n种 可以按值分块求答案

    代码还很短- -

    for (int i=1,last=0;i<=n && i<=m;i=last+1){
        last=std::min(n/(n/i),m/(m/i));
        res+=(sum[last]-sum[i-1])*(n/i)*(m/i);
    }
  • 相关阅读:
    机器学习:随机森林RF-OBB袋外错误率
    直观判断图像是否可以被实时处理
    职业:图像处理入门教程
    Caffe+Kubuntu16.04_X64+CUDA 8.0配置
    Photoshop显示RGB值问题
    统计:mAP的中文意思
    三维重建:多点透视cvSolvePNP的替代函数(Code)
    SLAM:ORB-SLAM 位姿优化描述
    MxNet : use the MxNet windows versioin
    Python 遍历目录
  • 原文地址:https://www.cnblogs.com/g-word/p/3742705.html
Copyright © 2020-2023  润新知