当作杜教筛的笔记吧。

杜教筛

要求一个积性函数$f(i)$的前缀和,现在这个东西并不是很好算,那么我们考虑让它卷上另外一个积性函数$g(i)$,使$(f * g)$的前缀和变得方便计算,然后再反推出这个$f$函数的前缀和。

$$\sum_{i = 1}^{n}(f * g)(i) = \sum_{i = 1}^{n}\sum_{d | i}g(d)f(\frac{i}{d}) = \sum_{d = 1}^{n}g(d)\sum_{i = 1}^{\left \lfloor \frac{n}{d} \right \rfloor}f(i) = \sum_{d = 1}^{n}g(d)S(\frac{n}{d}{})$$

把$g(1)S(n)$移过来

$$g(1)S(n) = \sum_{i = 1}^{n}(f * g)(i) - \sum_{i = 2}^{n}g(i)S(\left \lfloor \frac{n}{i} \right \rfloor)$$

这个式子就是杜教筛的精髓了。

我们可以先筛出$[1, \sqrt{n}]$区间内的该积性函数的前缀和,然后再分块递归求解$(\sqrt{n}, n]$中的该函数的前缀和,可以做到$O(n^{\frac{2}{3}})$的优秀的复杂度(并不会这个复杂度的证明)。

应该用一个哈希表存一下已经计算过的各个$S(n)$的值($unordered\_map$)。

接下来的问题就是考虑如何搭配出这个积性函数$g$了。

模板题

考虑如何计算$\mu$和$\varphi$。

我们知道$\mu * I = \epsilon$,那么有

$$S(n) = \sum_{i = 1}^{n}\epsilon(i) - \sum_{i = 2}^{n}S(\left \lfloor \frac{n}{i} \right \rfloor)$$

滑稽吧,$\epsilon$的前缀和还不是$1$。

我们又知道$\varphi * I = id$,那么又有

$$S(n) = \sum_{i = 1}^{n}id(i) - \sum_{i = 2}^{n}S(\left \lfloor \frac{n}{i} \right \rfloor)$$

而$\sum_{i = 1}^{n}id(i) = \sum_{i = 1}^{n}i = \frac{i(i + 1)}{2}$。

解决了!

Code:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <unordered_map>
  4. using namespace std;
  5. typedef long long ll;
  6.  
  7. const int N = 5e6 + ;
  8. const int Maxn = 5e6;
  9.  
  10. int testCase, pCnt = , pri[N], mu[N], phi[N];
  11. ll sumMu[N], sumPhi[N];
  12. bool np[N];
  13. unordered_map <int, ll> sMu, sPhi;
  14.  
  15. template <typename T>
  16. inline void read(T &X) {
  17. X = ; char ch = ; T op = ;
  18. for (; ch > ''|| ch < ''; ch = getchar())
  19. if (ch == '-') op = -;
  20. for (; ch >= '' && ch <= ''; ch = getchar())
  21. X = (X << ) + (X << ) + ch - ;
  22. X *= op;
  23. }
  24.  
  25. inline void sieve() {
  26. mu[] = , phi[] = ;
  27. for (int i = ; i <= Maxn; i++) {
  28. if (!np[i]) pri[++pCnt] = i, phi[i] = i - , mu[i] = -;
  29. for (int j = ; j <= pCnt && i * pri[j] <= Maxn; j++) {
  30. np[i * pri[j]] = ;
  31. if (i % pri[j] == ) {
  32. phi[i * pri[j]] = phi[i] * pri[j];
  33. mu[i * pri[j]] = ;
  34. break;
  35. }
  36. phi[i * pri[j]] = phi[i] * phi[pri[j]];
  37. mu[i * pri[j]] = -mu[i];
  38. }
  39. }
  40.  
  41. for (int i = ; i <= Maxn; i++) {
  42. sumMu[i] = sumMu[i - ] + mu[i];
  43. sumPhi[i] = sumPhi[i - ] + phi[i];
  44. }
  45. }
  46.  
  47. ll getPhi(int n) {
  48. if (n <= Maxn) return sumPhi[n];
  49. if (sPhi[n]) return sPhi[n];
  50. ll res = 1LL * n * (n + ) / ;
  51. for (int l = , r; l <= n; l = r + ) {
  52. r = (n / (n / l));
  53. res -= 1LL * (r - l + ) * getPhi(n / l);
  54. }
  55. return sPhi[n] = res;
  56. }
  57.  
  58. ll getMu(int n) {
  59. if (n <= Maxn) return sumMu[n];
  60. if (sMu[n]) return sMu[n];
  61. ll res = 1LL;
  62. for (int l = , r; l <= n; l = r + ) {
  63. r = (n / (n / l));
  64. res -= 1LL * (r - l + ) * getMu(n / l);
  65. }
  66. return sMu[n] = res;
  67. }
  68.  
  69. int main() {
  70. sieve();
  71. read(testCase);
  72. for (int n; testCase--; ) {
  73. read(n);
  74. printf("%lld %lld\n", getPhi(n), getMu(n));
  75. }
  76. return ;
  77. }

感觉时限特别急,能别开$long \ long$就别开。

Luogu 4213 【模板】杜教筛(Sum)的更多相关文章

  1. p4213 【模板】杜教筛(Sum)

    传送门 分析 我们知道 $\varphi * 1 = id$ $\mu * 1 = e$ 杜教筛即可 代码 #include<iostream> #include<cstdio> ...

  2. [模板] 杜教筛 && bzoj3944-Sum

    杜教筛 浅谈一类积性函数的前缀和 - skywalkert's space - CSDN博客 杜教筛可以在\(O(n^{\frac 23})\)的时间复杂度内利用卷积求出一些积性函数的前缀和. 算法 ...

  3. luoguP4213 [模板]杜教筛

    https://www.luogu.org/problemnew/show/P4213 同 bzoj3944 考虑用杜教筛求出莫比乌斯函数前缀和,第二问随便过,第一问用莫比乌斯反演来做,中间的整除分块 ...

  4. LG4213 【模板】杜教筛(Sum)和 BZOJ4916 神犇和蒟蒻

    P4213 [模板]杜教筛(Sum) 题目描述 给定一个正整数$N(N\le2^{31}-1)$ 求 $$ans_1=\sum_{i=1}^n\varphi(i)$$ $$ans_2=\sum_{i= ...

  5. 51NOD 1222 最小公倍数计数 [莫比乌斯反演 杜教筛]

    1222 最小公倍数计数 题意:求有多少数对\((a,b):a<b\)满足\(lcm(a,b) \in [1, n]\) \(n \le 10^{11}\) 卡内存! 枚举\(gcd, \fra ...

  6. BZOJ3944: Sum(杜教筛模板)

    BZOJ3944: Sum(杜教筛模板) 题面描述 传送门 题目分析 求\(\sum_{i=1}^{n}\mu(i)\)和\(\sum_{i=1}^{n}\varphi(i)\) 数据范围线性不可做. ...

  7. luoguP4213 【模板】杜教筛(Sum)杜教筛

    链接 luogu 思路 为了做hdu来学杜教筛. 杜教筛模板题. 卡常数,我加了register居然跑到不到800ms. 太深了. 代码 // luogu-judger-enable-o2 #incl ...

  8. [bzoj3944] sum [杜教筛模板]

    题面: 传送门 就是让你求$ \varphi\left(i\right) $以及$ \mu\left(i\right) $的前缀和 思路: 就是杜教筛的模板 我们把套路公式拿出来: $ g\left( ...

  9. [洛谷P4213]【模板】杜教筛(Sum)

    题目大意:给你$n$,求:$$\sum\limits_{i=1}^n\varphi(i),\sum\limits_{i=1}^n\mu(i)$$最多$10$组数据,$n\leqslant2^{31}- ...

随机推荐

  1. Python学习-数据运算

    在Python中有丰富的算术运算,这使得Python在科学计算领域有着很高的地位,Python可以提供包括四则运算在内的各种算术运算. a = 10 b = 20 print(a-b) #-10 pr ...

  2. 在IIS站点中使用数字证书

    1. SSL解析(内容来自百度百科) SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安 ...

  3. 洛谷 1514 (NOIp2010) 引水入城

    题目:https://www.luogu.org/problemnew/show/P1514 如果有解,一个第一行的格子能覆盖第n行的一定是一个连续的区间. 因为如果不连续,则有围住了一些第n行的格子 ...

  4. MySQL连接查询、联合查询、子查询

    参考地址:http://blog.csdn.net/u011277123/article/details/54863371 1.MySQL连接查询 连接查询:将多张表(>=2)进行记录的连接(按 ...

  5. unidac 执行Execute后取得受影响行数。

    unidac 执行Execute后取得受影响行数. uniQuery2.SQL.Text := mmo2.Text; uniQuery2.Execute; mmo1.Lines.Add(Format( ...

  6. DHCP(一)

    DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)是一个局域网的网络协议,使用UDP协议工作, 主要有两个用途:给内部网络或网络服务供应商自动分配IP ...

  7. ffmpeg摄像头采集h264编码RTP发送

    一. 相关API说明 1. av_register_all 2. avformat_network_init 不管是流媒体发送还是流媒体接收, 需要先执行该函数. 3. avformat_alloc_ ...

  8. 安装并配置工具以使用iOS进行构建

    Visual Studio 2015   Visual Studio文档的新家是docs.microsoft.com上的Visual Studio 2017文档 . 有关Visual Studio 2 ...

  9. 【转】使用JMeter测试你的EJB

    对EJB进行一些性能基准测试是非常有必要和有帮助的,测试的方法和工具有很多,不过我最近发现,Apache JMeter是进行基准测试的一个优秀工具.可惜的是,JMeter没有提供一个可测试任意EJB的 ...

  10. selenium自动化浏览器后台运行headless模式

    通过selenium做WEB自动化的时候,必须要启动浏览器, 浏览器的启动与关闭会影响执行效率. 当我们在自己电脑运行代码时,还会影响做别的事情. 鉴于这种情况,Google针对Chrome浏览器新增 ...