• QQ 数(number.pas/c/cpp)——莫比乌斯函数


    题目

    【问题描述】
    企鹅国数学家 QQ 潜心研究数论,终于发现了一个简单的数论问题!
    一个 QQ 数定义为一个拥有一个大于 $ 1 $ 的完全平方数为因子的数字,一个数字的 QQ 值定义为这个数是 QQ 数的因数个数。
    现在 QQ 想知道在 $[L,R]$ 范围内,每个整数的 QQ 值之和是多少?
    你只需要告诉他这个数字,他就可以给你宝贵的 $ 10 $ 分作为一个奖励!
    【输入格式】
    第一行两个整数 $ L, R $ 代表要求的数字范围;
    【输出格式】
    输出一个整数表示 `L~R` 里每个数字的 QQ 值之和。
    【输入样例】
    1 10
    【输出样例】
    4
    【样例说明】
    4 的 QQ 值为 1,8 的 QQ 值为 2,9 的 QQ 值为 1。
    【数据范围】
    对于 $ 10\% $ 的数据,$ Rleq 10^4 $;
    对于另外 $ 30\% $ 的数据,$ Rleq 10^6 $;
    对于另外 $ 10\% $的数据,$ R leq 10^7 $;
    对于 $ 100\% $的数据,$ 1 leq Lleq R leq 10^9 $;

    题解

    因为 $ mu(i) $ 含有平方因子的值为0,于是可以巧妙利用这个性质

    记 $ [1,n] $ 的值为
    $ sum_{i=1}^{n} sum_{d|i}[1-mu(d)] $
    $ =sum_{d=1}^n[1-mu(d)^2] lfloor frac{n}{d} floor $
    $ =sum_{d=1}^n lfloor frac{n}{d} floor - sum_{d=1}^n lfloor frac{n}{d} floor mu(d)^2 $

    然后可以发现前面的 $ sum_{d=1}^n lfloor frac{n}{d} floor $ 可以分块,但后面的 $ sum_{d=1}^n lfloor frac{n}{d} floor mu(d)^2 n leq 10^9 $,没有办法预处理

    考虑 $ sum_{d=1}^n lfloor frac{n}{d} floor mu(d)^2 $ 的几何意义

    $ sum_{d=1}^n lfloor frac{n}{d} floor mu(d)^2 = n- lfloor frac{n}{2} floor - lfloor frac{n}{3} floor -lfloor frac{n}{5} floor + lfloor frac{n}{6} floor +... $

    可以发现当 $ i> sqrt{n} $ 时 $ lfloor frac{n}{i} floor = 0$

    所以只要枚举到 $ sqrt{n} $ 时即可(其实还是可以分块优化的)

    然后就可以在 $ O(sqrt{n}) $ 完成


    再附一种做法:

    $ -sum_{i=2}^{sqrt{n}}mu(i)sum_{j=1}^{lfloor frac{n}{i^2 j} floor} lfloor frac{n}{i^2 j} floor $ 直接分块即可

    代码

     1 #include<bits/stdc++.h>
     2 #define LL long long
     3 #define _(d) while(d(isdigit(ch=getchar())))
     4 using namespace std;
     5 int R(){
     6     int x;bool f=1;char ch;_(!)if(ch=='-')f=0;x=ch^48;
     7     _()x=(x<<3)+(x<<1)+(ch^48);return f?x:-x;}
     8 const int N=1e7+5;
     9 int p[N],vis[N],mu[N],l,r,tot;
    10 LL make(int n){
    11     LL ans=0;
    12     for(int i=1;i*i<=n;i++)
    13         ans+=mu[i]*(n/(i*i));
    14     return ans;
    15 }
    16 LL work(int n){
    17     LL ans=0,res=0;
    18     for(int i=1,l;i<=n;i=l+1)
    19         l=n/(n/i),ans+=(n/i)*(l-i+1);
    20     for(int i=1,l;i<=n;i=l+1)
    21         l=n/(n/i),res+=(n/i)*(make(l)-make(i-1));
    22     return ans-res;
    23 }
    24 int main(){
    25     mu[1]=1;
    26     for(int i=2;i<N;i++){
    27         if(!vis[i])p[++tot]=i,mu[i]=-1;
    28         for(int j=1;j<=tot&&p[j]*i<N;j++){
    29             vis[i*p[j]]=1;
    30             if(i%p[j]==0)break;
    31             mu[i*p[j]]=-mu[i];
    32         }
    33     }
    34     l=R(),r=R();
    35     printf("%lld
    ",work(r)-work(l-1));
    36     return 0;
    37 }
    View Code

    2019-03-20

  • 相关阅读:
    webrtc连接方法——TURN服务器和STUN服务器作用简介
    IM音视频即时通讯系统EasyRTC如何利用webrtc技术进行优化和发展?
    TSINGSEE青犀视频平台可以实现音视频混流吗?
    深入浅出Java 重定向和请求转发的区别
    特征工程-特征提取
    cart剪枝
    决策树算法简介
    逻辑回归介绍
    sklearn模型的保存和加载
    celery 定时任务时间篇
  • 原文地址:https://www.cnblogs.com/chmwt/p/10566003.html
Copyright © 2020-2023  润新知