【bzoj3944/bzoj4805】Sum/欧拉函数求和 杜教筛
bzoj3944
题目描述
输入
输出
样例输入
6
1
2
8
13
30
2333
样例输出
1 1
2 0
22 -2
58 -3
278 -3
1655470 2
bzoj4805
同上,不需要求mu
题解
杜教筛
公式推导:

这里有一个难点(其实也不能算难),就是由枚举d|i到枚举j≤⌊n/i⌋。此时可以看作下面语句的i是上面语句的i/d,而下面语句的j就是上面语句的d。这样枚举的话,不会出现重复或遗漏,不会超过n,并且便于计算。
推出这个式子之后,枚举⌊n/i⌋的取值(最多只有√n种),用记忆化搜索的方法记录每次的sum(⌊n/i⌋),并累计到sum(n)中。这里需要使用map。
这样做的时间复杂度是O(n3/4logn),如果预处理出n2/3以内的phi值,就能使时间复杂度达到更小的O(n2/3logn)。
这样就解决了bzoj4805。对于bzoj3944还需要求莫比乌斯函数的前缀和,方法和欧拉函数非常类似,运用到了∑mu(d)(d|n)=1的性质,只需要把n(n+1)/2换成1即可。
bzoj3944:
#include <cstdio>
#include <map>
#include <utility>
#define N 3000010
using namespace std;
typedef long long ll;
map<ll , pair<ll , ll> > f;
map<ll , pair<ll , ll> >::iterator it;
ll phi[N] , mu[N] , prime[N] , tot , sumphi[N] , summu[N] , m = 3000000;
bool np[N];
void query(ll n , ll &ans1 , ll &ans2)
{
if(n <= m)
{
ans1 = sumphi[n] , ans2 = summu[n];
return;
}
it = f.find(n);
if(it != f.end())
{
ans1 = it->second.first , ans2 = it->second.second;
return;
}
ans1 = n * (n + 1) / 2 , ans2 = 1;
ll i , last , tmp1 , tmp2;
for(i = 2 ; i <= n ; i = last + 1)
{
last = n / (n / i) , query(n / i , tmp1 , tmp2);
ans1 -= (last - i + 1) * tmp1 , ans2 -= (last - i + 1) * tmp2;
}
f[n] = make_pair(ans1 , ans2);
}
int main()
{
int T;
ll n , i , j , ans1 , ans2;
np[1] = 1 , mu[1] = phi[1] = sumphi[1] = summu[1] = 1;
for(i = 2 ; i <= m ; i ++ )
{
if(!np[i]) prime[++tot] = i , phi[i] = i - 1 , mu[i] = -1;
for(j = 1 ; j <= tot && i * prime[j] <= m ; j ++ )
{
np[i * prime[j]] = 1;
if(i % prime[j] == 0)
{
phi[i * prime[j]] = phi[i] * prime[j] , mu[i * prime[j]] = 0;
break;
}
else phi[i * prime[j]] = phi[i] * (prime[j] - 1) , mu[i * prime[j]] = -mu[i];
}
sumphi[i] = sumphi[i - 1] + phi[i] , summu[i] = summu[i - 1] + mu[i];
}
scanf("%d" , &T);
while(T -- ) scanf("%lld" , &n) , query(n , ans1 , ans2) , printf("%lld %lld\n" , ans1 , ans2);
return 0;
}
bzoj4805:
#include <cstdio>
#include <map>
#define N 1600010
using namespace std;
typedef long long ll;
map<ll , ll> f;
map<ll , ll>::iterator it;
ll m = 1600000 , phi[N] , prime[N] , tot , sum[N];
bool np[N];
ll query(ll n)
{
if(n <= m) return sum[n];
it = f.find(n);
if(it != f.end()) return it->second;
ll ans = n * (n + 1) / 2 , i , last;
for(i = 2 ; i <= n ; i = last + 1) last = n / (n / i) , ans -= (last - i + 1) * query(n / i);
f[n] = ans;
return ans;
}
int main()
{
ll i , j , n;
phi[1] = sum[1] = 1;
for(i = 2 ; i <= m ; i ++ )
{
if(!np[i]) phi[i] = i - 1 , prime[++tot] = i;
for(j = 1 ; j <= tot && i * prime[j] <= m ; j ++ )
{
np[i * prime[j]] = 1;
if(i % prime[j] == 0)
{
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
else phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
sum[i] = sum[i - 1] + phi[i];
}
scanf("%lld" , &n);
printf("%lld\n" , query(n));
return 0;
}
【bzoj3944/bzoj4805】Sum/欧拉函数求和 杜教筛的更多相关文章
- 【BZOJ3944/4805】Sum/欧拉函数求和 杜教筛
[BZOJ3944]Sum Description Input 一共T+1行 第1行为数据组数T(T<=10) 第2~T+1行每行一个非负整数N,代表一组询问 Output 一共T行,每行两个用 ...
- BZOJ4805: 欧拉函数求和(杜教筛)
4805: 欧拉函数求和 Time Limit: 15 Sec Memory Limit: 256 MBSubmit: 614 Solved: 342[Submit][Status][Discus ...
- BZOJ 4805: 欧拉函数求和 杜教筛
https://www.lydsy.com/JudgeOnline/problem.php?id=4805 给出一个数字N,求sigma(phi(i)),1<=i<=N https://b ...
- LOJ6686 Stupid GCD(数论,欧拉函数,杜教筛)
做题重心转移到 LOJ 了. 至于为什么,如果你知道“……”的密码,就去看吧. LOJ 上用户自创题大多数都不可做,今天看到个可做题(而且还是个水题),就来做了一发. 明显枚举立方根.(以下令 $m= ...
- 51 NOD 1239 欧拉函数之和(杜教筛)
1239 欧拉函数之和 基准时间限制:3 秒 空间限制:131072 KB 分值: 320 难度:7级算法题 收藏 关注 对正整数n,欧拉函数是小于或等于n的数中与n互质的数的数目.此函数以其首名研究 ...
- 【51nod】1239 欧拉函数之和 杜教筛
[题意]给定n,求Σφ(i),n<=10^10. [算法]杜教筛 [题解] 定义$s(n)=\sum_{i=1}^{n}\varphi(i)$ 杜教筛$\sum_{i=1}^{n}(\varph ...
- 51nod1244 欧拉函数之和 杜教筛
和上一题差不多,一个是μ*I=e,一个是φ*I=Id 稍改就得到了这题的代码 (我会告诉你我一开始逆元算错了吗) #include <bits/stdc++.h> #define MAX ...
- 【BZOJ4805】欧拉函数求和(杜教筛)
[BZOJ4805]欧拉函数求和(杜教筛) 题面 BZOJ 题解 好久没写过了 正好看见了顺手切一下 令\[S(n)=\sum_{i=1}^n\varphi(i)\] 设存在的某个积性函数\(g(x) ...
- 【BZOJ4805】欧拉函数求和
题面 Description 给出一个数字N,求\(\sum\limits_{i=1}^n\varphi(i)\)i,1<=i<=N Input 正整数N.N<=2*10^9 Out ...
随机推荐
- 高级vim 配置
[root@chenbj ~]# pwd /root [root@chenbj ~]# cat .vimrc set nocompatible set pastetoggle=<F9> s ...
- Bootstrap 折叠(collapse)插件面板
折叠插件(collapse)可以很容易地让页面区域折叠起来, 无论您是用它来创建折叠导航还是内容面板,它都允许很多内容选项. 您可以使用折叠插件 1.创建可折叠的分组或折叠的面板 <!DOCTY ...
- 零基础快速入门SpringBoot2.0 (一)
零基础快速入门SpringBoot2.0 (一) 一.SpringBoot2.x依赖环境和版本新特性说明 简介:讲解新版本依赖环境和springboot2新特性概述 1.依赖版本jdk8以上, Spr ...
- 理解Express 中间件
Express 中间件 Express程序基本上是一系列中间件函数的调用.中间件就是一个函数, 接受 req.res.next几个参数. 中间件函数可以执行任何代码, 对请求和响应对象进行修改, 结束 ...
- WireShark抓包命令
本机环回包 在进行通信开发的过程中,我们往往会把本机既作为客户端又作为服务器端来调试代码,使得本机自己和自己通信.但是wireshark此时是无法抓取到数据包的,需要通过简单的设置才可以. 具体方法如 ...
- 07.VUE学习之解决phpstorm不识别ECMASCRIPT6语法的问题
此时已经识别:
- Thread 小总结
目录 线程概述 线程的定义 线程的启动 线程的状态 线程的方法属性 1.线程概述 线程是一个程序的多个执行路径,执行调度的单元,依托于进程的存在.线不仅可以共享进程的内在,而且还拥有一个属于自己的内存 ...
- Keywords Search HDU - 2222 ( ac自动机)模版题
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- HDU1505-City Game(记忆化搜索)
City Game http://acm.hdu.edu.cn/showproblem.php?pid=1505 Problem Description Bob is a strategy game ...
- Ubuntu下Python无法识别中文
在NLP的相关任务中,应用python处理中文是很常见的.在这个过程中,由于编码方式的不一致,可能会出现以下两种错误: 1)SyntaxError: Non-ASCII character in f ...