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

题解:杜教筛,用来求$\sum\limits_{i=1}^nf(i)$的,其中$f$是某个特殊函数。

若我们可以找到一个函数$g$,使得$g,f*g$两个函数的前缀和十分好算($g*f$表示$g$和$f$的狄利克雷卷积),就可在$O(n^{\frac 23})$的复杂度内求出我们要的东西。令$S(n)=\sum\limits_{i=1}^nf(i)$
$$
\begin{align*}
\sum\limits_{i=1}^n(g*f)(i)&=\sum\limits_{i=1}^n\sum\limits_{d|i}g(d)f\left(\dfrac id\right)\\
&=\sum\limits_{d=1}^ng(d)\sum\limits_{i=1,d|i}^nf\left(\dfrac id\right)\\
&=\sum\limits_{d=1}g(d)S\left(\left\lfloor\dfrac nd\right\rfloor\right)
\end{align*}\\
g(1)S(n)=\sum\limits_{i=1}^n(f*g)(i)-\sum\limits_{i=2}^ng(i)S\left(\left\lfloor\dfrac ni\right\rfloor\right)
$$
然后线性筛求出前$n^{\frac23}$项,剩余的递归+整除分块计算,需要记忆化。

$$
\sum\limits_{i=1}^n\varphi(i):\\
\because\varphi*I=id\\
\therefore S(n)=\frac{n(n+1)}{2}-\sum_{i=2}^nS\left(\left\lfloor\dfrac n i\right\rfloor\right)
$$
$$
\sum\limits_{i=1}^n\mu(i):\\
\because\mu*I=1\\
\therefore S(n)=1-\sum_{i=2}^nS\left(\left\lfloor\frac n i\right\rfloor\right)
$$

注意这道题中$n\leqslant2^{31}-1$,$+1$后会爆$int$,所以整除分块的时候要用$unsigned$

卡点:无

C++ Code:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <unordered_map>
const int R = 1 << 22 | 1;
int plist[R >> 3], ptot;
bool notp[R];
long long phi[R], mu[R];
void sieve() {
phi[1] = mu[1] = 1;
for (int i = 2; i < R; ++i){
if (!notp[i]) plist[ptot++]=i, phi[i] = i - 1, mu[i] = -1;
for(int j = 0, t; (t = i * plist[j]) < R; ++j){
notp[t] = true;
if(i % plist[j] == 0) {
phi[t] = phi[i] * plist[j];
mu[t] = 0;
break; }
phi[t] = phi[i] * phi[plist[j]];
mu[t] = -mu[i];
}
}
for (int i = 2; i < R; ++i) phi[i] += phi[i - 1], mu[i] += mu[i - 1];
}
std::unordered_map<unsigned, long long> Phi, Mu;
long long sphi(unsigned n) {
if (n < R) return phi[n];
if (Phi.count(n)) return Phi[n];
long long &t = Phi[n];
for (unsigned l = 2, r; l <= n; l = r + 1) {
r = n / (n / l);
t += (r - l + 1) * sphi(n / l);
}
return t = static_cast<long long> (n + 1) * n / 2 - t;
}
long long smu(unsigned n) {
if (n < R) return mu[n];
if (Mu.count(n)) return Mu[n];
long long &t = Mu[n];
for (unsigned l = 2, r; l <= n; l = r + 1) {
r = n / (n / l);
t += (r - l + 1) * smu(n / l);
}
return t = 1 - t;
} int T;
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cin.tie(0);
sieve();
std::cin >> T;
while (T --> 0) {
static unsigned n;
std::cin >> n;
std::cout << sphi(n) << ' ' << smu(n) << '\n';
}
return 0;
}

  

[洛谷P4213]【模板】杜教筛(Sum)的更多相关文章

  1. 洛谷P4213(杜教筛)

    #include <bits/stdc++.h> using namespace std; typedef long long LL; const int maxn = 3e6 + 3; ...

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

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

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

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

  4. luoguP4213 [模板]杜教筛

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

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

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

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

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

  7. 洛谷P4213 Sum(杜教筛)

    题目描述 给定一个正整数N(N\le2^{31}-1)N(N≤231−1) 求ans_1=\sum_{i=1}^n\phi(i),ans_2=\sum_{i=1}^n \mu(i)ans1​=∑i=1 ...

  8. P4213 【模板】杜教筛(Sum)

    \(\color{#0066ff}{题 目 描 述}\) 给定一个正整数\(N(N\le2^{31}-1)\) 求 \(\begin{aligned} ans_1=\sum_{i=1}^n\varph ...

  9. P4213【模板】杜教筛(Sum)

    思路:杜教筛 提交:\(2\)次 错因:\(\varphi(i)\)的前缀和用\(int\)存的 题解: 对于一类筛积性函数前缀和的问题,杜教筛可以以低于线性的时间复杂度来解决问题. 先要构造\(h= ...

随机推荐

  1. 手动停止jquery ajax请求

    主要调用jquery提供的ajax abort方法,详细代码如下: <html> <head> <meta charset="UTF-8"> & ...

  2. GoCN每日新闻(2019-10-10)

    GoCN每日新闻(2019-10-10) GoCN每日新闻(2019-10-10) 1. Go语言源码阅读之bytes.Buffer http://www.pengrl.com/p/60618/ 2. ...

  3. 「APIO2018」选圆圈

    传送门 Description 有\(n\)个圆,每次找到这些圆中半径最大中的编号最小的圆,删除ta及与其有交集的所有圆. 对于每个圆,求出它是被哪一个圆删除的. Solution  K-D Tree ...

  4. C++2.0新特性(六)——<Smart Pointer(智能指针)之shared_ptr>

    Smart Pointer(智能指针)指的是一类指针,并不是单一某一个指针,它能知道自己被引用的个数以至于在最后一个引用消失时销毁它指向的对象,本文主要介绍C++2.0提供的新东西 一.Smart P ...

  5. Linux 上配置 AG

    SQL Server Always On Availability Group 配置步骤:配置三台 Linux 集群节点创建 Availability Group配置 Cluster Resource ...

  6. 因在缓存对象中增加字段,而导致Redis中取出缓存转化成Java对象时出现反序列化失败的问题

    背景描述 因为业务需求的需要,我们需要在原来项目中的一个DTO类中新增两个字段(我们项目使用的是dubbo架构,这个DTO在A项目/服务的domain包中,会被其他的项目如B.C.D引用到).但是这个 ...

  7. Spring Boot 面试,一个问题就干趴下了!(下)

    前些天栈长在Java技术栈微信公众号分享一篇文章:Spring Boot 面试,一个问题就干趴下了!,看到大家的留言很精彩,特别是说"约定大于配置"的这两个玩家. 哈哈,上墙的朋友 ...

  8. 多线程 interrupt()方法

    java interrupt()方法只是设置线程的中断标记,当对处于阻塞状态的线程调用interrupt方法时(处于阻塞状态的线程是调用sleep, wait, join 的线程),会抛出Interr ...

  9. vue中使用百度地图vue-baidu-map

    安装 npm install vue-baidu-map --save 全局注册 全局注册将一次性引入百度地图组件库的所有组件.需在入口文件main.js中引入vue-baidu-map import ...

  10. hangfire控制台应用程序中添加控制面板

    1.使用nuget 管理包安装 Microsoft.AspNet.WebApi.OwinSelfHost 2.根目录添加新建类 名为:Startup.cs public class Startup { ...