P4213 【模板】杜教筛(杜教筛)题解
题意:
求\(\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;
}
转载于:https://www.cnblogs.com/KirinSB/p/11461267.html
P4213 【模板】杜教筛(杜教筛)题解相关推荐
- 杜教筛 (包括线筛) 莫比乌斯函数前缀和 欧拉函数前缀和 因数和函数前缀和 因子个数前缀和 ( 分析 )...
对于莫比乌斯函数 和 欧拉函数 小于 1e8差不多都可线筛 1e12以内 杜教筛 代码针对洛古 p4213 n<=(1<<31)-1 杜教筛 #include< ...
- 筛表合集(素数筛 欧拉函数筛 莫比乌斯函数筛)
[目录] 一.素数筛 1.素数判断 2.素数普通筛 3.素数线性筛 4.素数区间筛 二.欧拉函数筛 三.莫比乌斯函数筛 [素数筛] 1.直接判定质数 bool judgePrime( int num ...
- 埃氏筛与欧拉筛(线性筛)
目录 一.前言 二.埃氏筛与欧拉筛(线性筛) 1.问题描述 2.基本思路 (1)埃氏筛法 (2)欧拉筛法 三.题例 1.上链接 2.简单思路 3.代码 (1)埃氏筛python版 (2)欧拉筛pyth ...
- 埃氏筛 线性筛(欧拉筛) 算法解析
埃氏晒 埃拉托斯特尼筛法,简称埃氏晒,是一种用来求自然数n以内的全部素数. 他的基本原理是,如果我们要获得小于n的所有素数,那就把不大于根号n的所有素数的倍数剔除. 埃氏晒的原理很容易理解,一个合数, ...
- 素数的线性筛法java,埃氏筛 线性筛(欧拉筛) 算法解析
埃氏晒 埃拉托斯特尼筛法,简称埃氏晒,是一种用来求自然数n以内的全部素数. 他的基本原理是,如果我们要获得小于n的所有素数,那就把不大于根号n的所有素数的倍数剔除. 埃氏晒的原理很容易理解,一个合数, ...
- 杜比介绍 杜比数位 Dolby
杜比音效 上面符号,经常在电视机.电影院和投影仪上出现,说明设备支持杜比技术,在一定程度上可以给人带来较好的听觉体验,从二维立体声到三维全景声,给人一种空间感和沉浸感. 什么是杜比技术? 说到杜比技术 ...
- 算法笔记--素数筛(朴素筛,埃式筛,欧拉筛)
素数 素数也叫质数,是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数.如2 , 3 , 5 , 7 , 11等. 素数筛 素数筛即筛选出1~n内的素数的方法,这里介绍三种 常见的求素数 ...
- c语言 快速筛质数,快速筛素数(埃式筛+线性筛+Miller_Rabin算法)
在CF上做到一道核心是需要筛出1~n所有素数的题目,然后刚好又没学过,就学习了快速筛素数的办法,基础的n根号n的算法这里大家每个人都知道吧QAQ,就不讲了,好像还是C语言上机说过的题目. 首先给大家介 ...
- 筛选质数,埃氏筛和欧拉筛(线性筛)
求len之内的所有的素数 除了比较常用的开根号的求法,还有两种更好的方法,埃氏筛和线性筛.其中埃氏筛更好理解,而线性筛(欧拉筛)不好理解但是更快. 埃氏筛 #include <bits/stdc ...
- 计算机组装与拆解中容易混淆的知识点,教资干货 | 教资笔试中易混淆的知识点整合...
原标题:教资干货 | 教资笔试中易混淆的知识点整合 教师资格笔试越来越近, 同学们要会进行归纳整理和总结, 很多同学复习的很好, 但一看到题目的时候就不确定具体答案是哪个了, 今天小编就来归纳整理教资 ...
最新文章
- 比较有趣的一个笔试题目
- Hive代码组织及架构简单介绍
- 谷歌年度AI技术总结来了!Jeff Dean执笔,附赠27个开源工具和数据大礼包
- Mint-UI 的 DatetimePicker 日期时间插件的安装与使用
- android:background=@color/white [create file color.xml at res/values/]
- 跟风学Docker之四:Docker网络解决方案
- 倍福 在 vs 里 编程 是怎么做到的_截图里的文字要改,字体怎么做到一模一样?...
- matlab第七章符号对象,MATLAB语言:第七章 MATLAB符号计算
- 回溯____蓝桥 棋盘
- springboot 微服务_Spring Boot在微服务中的最佳实践
- 谷歌浏览器http请求之curl使用
- java 泰勒级数_使用rSymPy计算泰勒级数
- java word中插入图片_在Word文档中插入图片
- 蓝牙运动手环app开发方案
- 状态方程simulink仿真_控制系统设计与仿真作业与复习资料
- Mac系统重置快捷键
- android tf卡及u盘_android8.1系统修改第三方app无法读写U盘或者内部SD卡的问题
- HTML5 极简的JS函数
- 最新完整数据结构与算法
- TPAMI 2021 | 让时间走向二维,基于文本的视频时间定位新方法:MS-2D-TAN,兼顾速度与精度!...
热门文章
- eclipse修改xml文件默认的打开方式为XML Editor
- 关于消息中间件,我找了一些比较好玩的讨论主题,觉得对于深入理解一些技术问题非常有帮助...
- Greenplu数据库的部署
- Linux文件的三种特殊权限SUID、SGID、STICKY
- zabbix的Discovery功能
- HG8240电信光猫禁用TR069之修改配置法
- 数数FastJson那些年犯下的'血案'...
- 为什么阿里规定需要在事务注解@Transactional中指定rollbackFor
- 推荐几个我珍藏的公众号~超级无敌!
- 高级政工师具备的能力_广东省固体废弃物利用处置能力评价资质申报指南