码迷,mamicode.com
首页 > 其他好文 > 详细

QQ 数——莫比乌斯函数

时间:2019-03-20 17:36:29      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:its   code   col   char   ret   click   ide   利用   ons   

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\% $ 的数据,$ R\leq 10^4 $;
对于另外 $ 30\% $ 的数据,$ R\leq 10^6 $;
对于另外 $ 10\% $的数据,$ R \leq 10^7 $;
对于 $ 100\% $的数据,$ 1 \leq L\leq 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} \rfloor =\sum_{d=1}^n \lfloor \frac{n}{d} \rfloor - \sum_{d=1}^n \lfloor \frac{n}{d} \rfloor \mu(d)^2 $
然后可以发现前面的 $ \sum_{d=1}^n \lfloor \frac{n}{d} \rfloor $ 可以分块,但后面的 $ \sum_{d=1}^n \lfloor \frac{n}{d} \rfloor \mu(d)^2 \ n \leq 10^9 $,没有办法预处理
考虑 $ \sum_{d=1}^n \lfloor \frac{n}{d} \rfloor \mu(d)^2 $ 的几何意义
$ \sum_{d=1}^n \lfloor \frac{n}{d} \rfloor \mu(d)^2 = n- \lfloor \frac{n}{2} \rfloor - \lfloor \frac{n}{3} \rfloor -\lfloor \frac{n}{5} \rfloor + \lfloor \frac{n}{6} \rfloor +... $
可以发现当 $ i> \sqrt{n} $ 时 $ \lfloor \frac{n}{i} \rfloor = 0$
所以只要枚举到 $ \sqrt{n} $ 时即可(其实还是可以分块优化的)
然后就可以在 $ O(\sqrt{n}) $ 完成

再附一种做法:
$ -\sum_{i=2}^{\sqrt{n}}\mu(i)\sum_{j=1}^{\lfloor \frac{n}{i^2 j} \rfloor} \lfloor \frac{n}{i^2 j} \rfloor $ 直接分块即可

技术图片
 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\n",work(r)-work(l-1));
36     return 0;
37 }
View Code

2019-03-20

QQ 数——莫比乌斯函数

标签:its   code   col   char   ret   click   ide   利用   ons   

原文地址:https://www.cnblogs.com/chmwt/p/10566003.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!