[51Nod 1244] - 莫比乌斯函数之和 & [51Nod 1239] - 欧拉函数之和 (杜教筛板题)
[51Nod 1244] - 莫比乌斯函数之和
求∑i=1Nμ(i)\sum_{i=1}^Nμ(i)∑i=1Nμ(i)
开推
∑d∣nμ(d)=[n==1]\sum_{d|n}\mu(d)=[n==1]d∣n∑μ(d)=[n==1]
移项
μ(d)=[n==1]−∑d∣n,d<nμ(d)∴S(N)=∑i=1Nμ(i)=∑i=1N([i==1]−∑d∣i,d<iμ(d))=1−∑i=1N∑d∣i,d<iμ(d)\mu(d)=[n==1]-\sum_{d|n,d<n}\mu(d)\newline
\therefore S(N)=\sum_{i=1}^Nμ(i)=\sum_{i=1}^N([i==1]-\sum_{d|i,d<i}\mu(d))\newline
=1-\sum_{i=1}^N\sum_{d|i,d<i}\mu(d) \newlineμ(d)=[n==1]−d∣n,d<n∑μ(d)∴S(N)=i=1∑Nμ(i)=i=1∑N([i==1]−d∣i,d<i∑μ(d))=1−i=1∑Nd∣i,d<i∑μ(d)
此处是杜教筛的精髓,也是整除分块优化的精髓(或者说是转换方法),枚举i是d的多少倍
S(N)=1−∑⌊id⌋=2N∑d=1,1<⌊id⌋⌊N⌊id⌋⌋μ(d)S(N)=1-\sum_{{\lfloor{\frac id}\rfloor} =2}^N\sum_{d=1,1<{\lfloor{\frac id}\rfloor}}^{\lfloor \frac N{\lfloor{\frac id}\rfloor} \rfloor}\mu(d)S(N)=1−⌊di⌋=2∑Nd=1,1<⌊di⌋∑⌊⌊di⌋N⌋μ(d)
令k=⌊id⌋k={\lfloor{\frac id}\rfloor}k=⌊di⌋,则有
S(N)=1−∑k=2N∑d=1⌊Nk⌋μ(d)=1−∑k=2NS(⌊Nk⌋)S(N)=1-\sum_{k=2}^N\sum_{d=1}^{\lfloor \frac Nk\rfloor}\mu(d)
=1-\sum_{k=2}^NS({\lfloor \frac Nk\rfloor})S(N)=1−k=2∑Nd=1∑⌊kN⌋μ(d)=1−k=2∑NS(⌊kN⌋)
那么就可以用线性筛出前面一部分,再整除分块优化递归处理
杜教筛无预处理的时间复杂度是Θ(n34)\Theta(n^{\frac 34})Θ(n43)
预处理一定范围内的答案后就能降到Θ(n23)\Theta(n^{\frac 23})Θ(n32)
然而我们此处并不需要多小的时间复杂度…随便处理一个10710^7107就能过了
AC code
#include <cstdio>
#include <map>
#include <cstring>
#include <algorithm>
using namespace std;
#define LL long long
const int MAXP = 1e7+1;
int Prime[MAXP/10], Cnt, mu[MAXP], sum[MAXP];
bool IsnotPrime[MAXP];
map<LL,int>S;
void init(int N)
{
mu[1] = 1;
for(int i = 2; i <= N; ++i)
{
if(!IsnotPrime[i]) Prime[++Cnt] = i, mu[i] = -1;
for(int j = 1; j <= Cnt && i * Prime[j] <= N; ++j)
{
IsnotPrime[i * Prime[j]] = 1;
if(i % Prime[j] == 0) { mu[i * Prime[j]] = 0; break; }
mu[i * Prime[j]] = -mu[i];
}
}
for(int i = 1; i <= N; i++) sum[i] = sum[i-1] + mu[i];
}
inline int solve(LL N)
{
if(N < MAXP) return sum[N];
if(S.count(N)) return S[N];//记忆化,其实此处可以Hash或者用
int ret = 1;
for(LL i = 2, j; i <= N; i=j+1)
{
j = N/(N/i);
ret -= (j-i+1) * solve(N/i);
}
return S[N] = ret;
}
int main ()
{
LL n, m; init(MAXP-1);
scanf("%lld%lld", &n, &m);
printf("%d\n", solve(m)-solve(n-1));
}
[51Nod 1239] - 欧拉函数之和
求 ∑i=1Nφ(i)\sum_{i=1}^Nφ(i)∑i=1Nφ(i)
开推,有
∑d∣nφ(d)=n
\sum_{d|n}φ(d)=n
d∣n∑φ(d)=n
移项
φ(n)=n−∑d∣n,d<nφ(d)∴S(N)=∑i=1N(i−∑d∣i,d<iφ(d))=N∗(N+1)2−∑i=1N∑d∣i,d<iφ(d)=N∗(N+1)2−∑⌊id⌋=2N∑d=1⌊N⌊id⌋⌋φ(d)
φ(n)=n-\sum_{d|n,d<n}φ(d)\newline
\therefore S(N)=\sum_{i=1}^N(i-\sum_{d|i,d<i}φ(d))\newline
=\frac{N*(N+1)}2-\sum_{i=1}^N\sum_{d|i,d<i}φ(d)\newline
=\frac{N*(N+1)}2-\sum_{{\lfloor\frac id\rfloor}=2}^N\sum_{d=1}^{{\lfloor\frac N{{\lfloor\frac id\rfloor}}\rfloor}}φ(d)\newlineφ(n)=n−d∣n,d<n∑φ(d)∴S(N)=i=1∑N(i−d∣i,d<i∑φ(d))=2N∗(N+1)−i=1∑Nd∣i,d<i∑φ(d)=2N∗(N+1)−⌊di⌋=2∑Nd=1∑⌊⌊di⌋N⌋φ(d)
令k=⌊id⌋k={\lfloor{\frac id}\rfloor}k=⌊di⌋,则有
S(N)=N∗(N+1)2−∑k=2N∑d=1⌊Nk⌋φ(d)=N∗(N+1)2−∑k=2NS(⌊Nk⌋)
S(N)=\frac{N*(N+1)}2-\sum_{k=2}^N\sum_{d=1}^{{\lfloor\frac Nk\rfloor}}φ(d)\newline
=\frac{N*(N+1)}2-\sum_{k=2}^NS({\lfloor\frac Nk\rfloor})\newline
S(N)=2N∗(N+1)−k=2∑Nd=1∑⌊kN⌋φ(d)=2N∗(N+1)−k=2∑NS(⌊kN⌋)
然后…就没有了.像上一道题一样处理就完了
AC Code
#include <cstdio>
#include <map>
#include <cstring>
#include <algorithm>
using namespace std;
#define LL long long
const int MAXP = 5e6 + 1;
const int mod = 1e9 + 7;
const int inv2 = 500000004;
int Prime[MAXP/10], Cnt, phi[MAXP];
LL sum_phi[MAXP];
bool IsnotPrime[MAXP];
void init(int N)
{
phi[1] = 1;
for(LL i = 2; i <= N; ++i)
{
if(!IsnotPrime[i]) Prime[++Cnt] = i, phi[i] = i-1;
for(LL j = 1; j <= Cnt && i * Prime[j] <= N; ++j)
{
IsnotPrime[i * Prime[j]] = 1;
if(i % Prime[j] == 0)
{
phi[i * Prime[j]] = phi[i] * Prime[j];
break;
}
phi[i * Prime[j]] = phi[i] * (Prime[j]-1);
}
}
for(int i = 1; i <= N; i++)
sum_phi[i] = ((sum_phi[i-1] + phi[i]) % mod + mod) % mod;
}
map<LL, LL> S_phi;
inline LL solve_phi(LL N)
{
if(N < MAXP) return sum_phi[N];
if(S_phi.count(N)) return S_phi[N];
LL ret = (N%mod + 1) * (N%mod) % mod * inv2 % mod;
for(LL i = 2, j; i <= N; i=j+1)
{
j = N/(N/i);
ret = (ret - (j-i+1) % mod * solve_phi(N/i) % mod) % mod;
}
return S_phi[N] = ((ret + mod) % mod);
}
int main ()
{
init(MAXP-1); LL n;
scanf("%lld", &n);
printf("%lld\n", solve_phi(n));
}
[51Nod 1244] - 莫比乌斯函数之和 & [51Nod 1239] - 欧拉函数之和 (杜教筛板题)的更多相关文章
- 51 NOD 1239 欧拉函数之和(杜教筛)
1239 欧拉函数之和 基准时间限制:3 秒 空间限制:131072 KB 分值: 320 难度:7级算法题 收藏 关注 对正整数n,欧拉函数是小于或等于n的数中与n互质的数的数目.此函数以其首名研究 ...
- BZOJ_4802_欧拉函数_MR+pollard rho+欧拉函数
BZOJ_4802_欧拉函数_MR+pollard rho+欧拉函数 Description 已知N,求phi(N) Input 正整数N.N<=10^18 Output 输出phi(N) Sa ...
- 51nod 1239 欧拉函数之和(杜教筛)
[题目链接] https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1239 [题目大意] 计算欧拉函数的前缀和 [题解] 我们 ...
- 51nod 1237 最大公约数之和 V3【欧拉函数||莫比乌斯反演+杜教筛】
用mu写lcm那道卡常卡成狗(然而最后也没卡过去,于是写一下gcd冷静一下 首先推一下式子 \[ \sum_{i=1}^{n}\sum_{j=1}^{n}gcd(i,j) \] \[ \sum_{i= ...
- 51Nod 1239 欧拉函数前n项和 杜教筛
http://www.51nod.com/Challenge/Problem.html#!#problemId=1239 AC代码 #include <bits/stdc++.h> #de ...
- 【51nod】1239 欧拉函数之和 杜教筛
[题意]给定n,求Σφ(i),n<=10^10. [算法]杜教筛 [题解] 定义$s(n)=\sum_{i=1}^{n}\varphi(i)$ 杜教筛$\sum_{i=1}^{n}(\varph ...
- 【51nod】1239 欧拉函数之和
题解 写完上一道就开始写这个,大体上就是代码改了改而已= = 好吧,再推一下式子! \(\sum_{i = 1}^{n}i = \sum_{i = 1}^{n}\sum_{d | i}\phi(d) ...
- 51nod 1239 欧拉函数之和【欧拉函数+杜教筛】
和bzoj 3944比较像,但是时间卡的更死 设\( f(n)=\sum_{d|n}\phi(d) g(n)=\sum_{i=1}^{n}f(i) s(n)=\sum_{i=1}^{n}\phi(i) ...
- 51nod 1238 最小公倍数之和 V3 【欧拉函数+杜教筛】
首先题目中给出的代码打错了,少了个等于号,应该是 G=0; for(i=1;i<=N;i++) for(j=1;j<=N;j++) { G = (G + lcm(i,j)) % 10000 ...
随机推荐
- Mongodb索引实战
最近碰到这样的一个需求,一张酒店政策优惠表,我们要根据用户入住和离开的时间,计算一家酒店的最低价政策前10位,数据库表字段如下: 'hid':88, 酒店id 'date':20150530, 入住日 ...
- CodeForces-166B-Polygons
B. Polygons time limit per test:2 seconds memory limit per test:256 megabytes input:standard input o ...
- 题解 Luogu P1099 【树网的核】
这题是真的水啊... ------------ 昨天模拟赛考了这题,很多人都是O($n^3$)水过,但我认为,要做就做的足够好(其实是我根本没想到O($n^3$)的做法),然后就开始想O(n)的解法. ...
- AVR单片机教程——开发环境配置
今天去交大密院参观了设计展,无外乎两个主题:Arduino.Python. 关于Python,我印象最深的是一位Python程序员的话:你要硬核的话,可以去那边看Java. 拜托,都9102年了,Ja ...
- Linux 进程控制
分享知乎上看到的一句话,共勉: 学习周期分为学习,思考,实践,校正四个阶段,周期越短,学习效率越高. 前面讲的都是操作系统如何管理进程,接下来,看看用户如何进行进程控制. 1.进程创建 先介绍一下函数 ...
- Python开发【第二章】:数据类型
基本数据类型 一.整型 如: 18.73.84 整型具备如下功能: class int(object): """ int(x=0) -> int or long i ...
- Android--文件存取
import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundExc ...
- SQLSERVER查询存储过程内容
--使用语句查看一个存储过程的定义 EXEC sp_helptext 'Auth_BankCardAuthorize' --查询所有存储过程的名称以及定义 SELECT name, definitio ...
- linux学习之路(三)--centos7安装mysql(单点)
1.先检查系统是否装有mysql rpm -qa | grep mysql 返回空值,说明没有安装. 这里执行安装命令是无效的,因为centos-7默认是Mariadb,所以执行以下命令只是更新Mar ...
- Golang高并发抓取HTML图片
Golang高并发抓取HTML图片 使用准备 1.安装Golang 2.下载爬虫包 go get -v github.com/hunterhug/marmot/util go get -v githu ...