题意:

求\(\sum_{i=1}^n\varphi(i)\)和\(\sum_{i=1}^n\mu(i)\)

思路:

由性质可知:\(\mu*I=\epsilon,\varphi*I=id\)那么可得:

\[S_{\varphi}(n)=\sum_{i=1}^n\varphi(i)=\frac{(n+1)n}{2}-\sum_{i=2}^nS_{\varphi}(\lfloor\frac{n}{i}\rfloor)\\
S_{\mu}(n)\sum_{i=1}^n\mu(i)=1-\sum_{i=2}^nS_{\mu}(\lfloor\frac{n}{i}\rfloor)
\]

然后用现预处理一部分答案,然后数论分块其他答案,用记忆化记录中间答案。

很卡常...

还有一种不用\(map\)的方法,详见代码\(2\)。

代码:

#include<map>
#include<set>
#include<cmath>
#include<cstdio>
#include<stack>
#include<ctime>
#include<vector>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<iostream>
#include<algorithm>
#include<unordered_map>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const int maxn = 6000000 + 5;
const ll MOD = 998244353;
const ull seed = 131;
const int INF = 0x3f3f3f3f; int vis[maxn];
int prime[maxn], cnt;
int N = 6000000;
ll mu[maxn], phi[maxn];
unordered_map<int, int> mmu;
unordered_map<int, ll> mphi;
void init(int n){
cnt = 0;
mu[1] = 1;
phi[1] = 1;
for(int i = 2; i <= n; i++){
if(!vis[i]){
prime[cnt++] = i;
mu[i] = -1;
phi[i] = i - 1;
}
for(int j = 0; j < cnt && prime[j] * i <= n; j++){
vis[i * prime[j]] = 1;
if(i % prime[j] == 0){
mu[i * prime[j]] = 0;
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
mu[i * prime[j]] = -mu[i];
phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
} for(int i = 2; i <= n; i++){
phi[i] += phi[i - 1];
mu[i] += mu[i - 1];
}
} ll Sphi(int n){
if(n <= N) return phi[n];
if(mphi.count(n)) return mphi[n];
ll ans = 1LL * n * (1 + n) >> 1LL;
for(int l = 2, r; l <= n; l = r + 1){
r = min(n / (n / l), n);
ans -= (r - l + 1) * Sphi(n / l);
}
return mphi[n] = ans;
}
int Smu(int n){
if(n <= N) return mu[n];
if(mmu.count(n)) return mmu[n];
int ans = 1;
for(int l = 2, r; l <= n; l = r + 1){
r = min(n / (n / l), n);
ans -= (r - l + 1) * Smu(n / l);
}
return mmu[n] = ans;
} int main(){
init(N);
int T;
scanf("%d", &T);
while(T--){
int n;
scanf("%d", &n);
printf("%lld %d\n", Sphi(n), Smu(n));
}
return 0;
}
#include<map>
#include<set>
#include<cmath>
#include<cstdio>
#include<stack>
#include<ctime>
#include<vector>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<iostream>
#include<algorithm>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const int maxn = 6000000 + 5;
const ll MOD = 998244353;
const ull seed = 131;
const int INF = 0x3f3f3f3f;
int vis[maxn];
int prime[maxn], cnt;
int N = 6000000;
ll phi[maxn], mphi[100000];
int mu[maxn], mmu[100000];
int vis2[100000];
int n, up;
void init(int n){
cnt = 0;
mu[1] = 1;
phi[1] = 1;
for(int i = 2; i <= n; i++){
if(!vis[i]){
prime[cnt++] = i;
mu[i] = -1;
phi[i] = i - 1;
}
for(int j = 0; j < cnt && prime[j] * i <= n; j++){
vis[i * prime[j]] = 1;
if(i % prime[j] == 0){
mu[i * prime[j]] = 0;
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
mu[i * prime[j]] = -mu[i];
phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
} for(int i = 2; i <= n; i++){
phi[i] += phi[i - 1];
mu[i] += mu[i - 1];
}
}
int getmu(int x){
return x <= N? mu[x] : mmu[up / x];
}
ll getphi(int x){
return x <= N? phi[x] : mphi[up / x];
}
void solve(int n){
int t = up / n;
if(n <= N) return;
if(vis2[t]) return;
vis2[t] = 1;
mmu[t] = 1, mphi[t] = 1LL * n * (n + 1) / 2;
for(int l = 2, r; l <= n; l = r + 1){
r = n / (n / l);
solve(n / l);
mmu[t] -= (r - l + 1) * getmu(n / l);
mphi[t] -= (r - l + 1) * getphi(n / l);
}
} int main(){
init(N);
int T;
scanf("%d", &T);
while(T--){
scanf("%d", &n);
up = n;
if(n <= N) printf("%lld %d\n", phi[n], mu[n]);
else{
memset(vis2, 0, sizeof(vis2));
solve(n);
printf("%lld %d\n", mphi[1], mmu[1]);
}
}
return 0;
}

P4213 【模板】杜教筛(杜教筛)题解的更多相关文章

  1. 【51NOD 1847】奇怪的数学题(莫比乌斯反演,杜教筛,min_25筛,第二类斯特林数)

    [51NOD 1847]奇怪的数学题(莫比乌斯反演,杜教筛,min_25筛,第二类斯特林数) 题面 51NOD \[\sum_{i=1}^n\sum_{j=1}^nsgcd(i,j)^k\] 其中\( ...

  2. 【LOJ#572】Misaka Network 与求和(莫比乌斯反演,杜教筛,min_25筛)

    [LOJ#572]Misaka Network 与求和(莫比乌斯反演,杜教筛,min_25筛) 题面 LOJ \[ans=\sum_{i=1}^n\sum_{j=1}^n f(gcd(i,j))^k\ ...

  3. hdu6607 min25筛+杜教筛+伯努利数求k次方前缀和

    推导过程类似https://www.cnblogs.com/acjiumeng/p/9742073.html 前面部分min25筛,后面部分杜教筛,预处理min25筛需要伯努利数 //#pragma ...

  4. 素数筛&&欧拉筛

    折腾了一晚上很水的数论,整个人都萌萌哒 主要看了欧拉筛和素数筛的O(n)的算法 这个比那个一长串英文名的算法的优势在于没有多次计算一个数,也就是说一个数只筛了一次,主要是在%==0之后跳出实现的,具体 ...

  5. 欧拉筛,线性筛,洛谷P2158仪仗队

    题目 首先我们先把题目分析一下. emmmm,这应该是一个找规律,应该可以打表,然后我们再分析一下图片,发现如果这个点可以被看到,那它的横坐标和纵坐标应该互质,而互质的条件就是它的横坐标和纵坐标的最大 ...

  6. 【51nod1847】奇怪的数学题(Min_25筛+杜教筛)

    题面 传送门 题解 这题有毒--不知为啥的错误调了半天-- 令\(f(i)={sgcd(i)}\),那么容易看出\(f(i)\)就是\(i\)的次大质因子,用\(i\)除以它的最小质因子即可计算 于是 ...

  7. LOJ572. 「LibreOJ Round #11」Misaka Network 与求和 [莫比乌斯反演,杜教筛,min_25筛]

    传送门 思路 (以下令\(F(n)=f(n)^k\)) 首先肯定要莫比乌斯反演,那么可以推出: \[ ans=\sum_{T=1}^n \lfloor\frac n T\rfloor^2\sum_{d ...

  8. HDU 6706 huntian oy(杜教筛 + 一些定理)题解

    题意: 已知\(f(n,a,b)=\sum_{i=1}^n\sum_{j=1}^igcd(i^a-j^a,i^b-j^b)[gcd(i,j)=1]\mod 1e9+7\),\(n\leq1e9\),且 ...

  9. 欧拉筛(线性筛) & 洛谷 P3383 【模板】线性筛素数

    嗯.... 埃氏筛和欧拉筛的思想都是相似的: 如果一个数是素数,那么它的所有倍数都不是素数.... 这里主要介绍一下欧拉筛的思路:(欧拉筛的复杂度大约在O(n)左右... 定义一个prime数组,这个 ...

  10. 洛谷 P3383 【模板】线性筛素数-线性筛素数(欧拉筛素数)O(n)基础题贴个板子备忘

    P3383 [模板]线性筛素数 题目描述 如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内) 输入输出格式 输入格式: 第一行包含两个正整数N.M,分别表示查询的范 ...

随机推荐

  1. 带你走进memcache,老牌内存缓存技术

    一.核心优化概述 什么是优化:以更小的资源支持更大负载网站的运行,以小博大. 思路:尽量减少用户等待时间,节省系统资源开销,节省带宽使用. 优化什么地方?有三方面:Memcache内存缓存技术.静态化 ...

  2. Java多线程基础知识笔记(持续更新)

    多线程基础知识笔记 一.线程 1.基本概念 程序(program):是为完成特定任务.用某种语言编写的一组指令的集合.即指一段静态的代码,静态对象. 进程(process):是程序的一次执行过程,或是 ...

  3. 中断与系统调用深度分析(以网络编程接口SocketAPI为例)

    1.从计算机CPU与I/O设备的交互方式谈起 计算机CPU与I/O设备的交互方式有最早的程序查询(也叫轮询)方式,发展到后来的程序中断方式,DMA方式等.简单来说,最早的程序查询方式的机制是,CPU若 ...

  4. 指针锁定 Pointer Lock API 用法

    指针锁定 Pointer Lock API 通过它可以访问原始的鼠标运动(基于指针的相对位移 movementX / movementY),把鼠标事件的目标锁定到一个特定的元素,同时隐藏视图中的指针光 ...

  5. 配置Charles 设置手机代理并允许https请求

    前言: 在h5开发调试时,为实现手机app访问localhost地址,可以使用ip地址的方式,但一般公司app出于安全考虑,会限制只能访问其自有域名.因此,使用charles代理的方式 步骤 用手机代 ...

  6. C# socket 阻止模式与非阻止模式应用实例

    问题概述 最近在处理一些TCP客户端的项目,服务端是C语言开发的socket. 实际项目开始的时候使用默认的阻塞模式并未发现异常.代码如下 1 public class SocketService 2 ...

  7. libuv中实现tcp服务器

    目录 1.说明 2.libuv的tcp server 3.API简介 3.1.uv_tcp_init 3.2.uv_ip4_addr 3.3.uv_tcp_bind 3.4.uv_listen 3.5 ...

  8. 解决 win10 无法安装VS2019,visual studio installer下载进度始终为0

    解决 win10 无法安装VS2019,visual studio installer下载进度始终为0 目录 解决 win10 无法安装VS2019,visual studio installer下载 ...

  9. Hive语法小释

    阅读本文你可以获取: 1.数据库的查询 2.hive表的基本操作(建表三种常用方式.删除表.修改表.加载数据.内外表转换.添加分区.复制数据) 3.SQL到HiveQL的的一些不同点 1.   基本操 ...

  10. 正则r的作用

    >>> mm = "c:\\a\\b\\c" >>> mm 'c:\\a\\b\\c' >>> print(mm) c:\a\ ...