线性筛法求解欧拉函数以及欧拉反演

欧拉函数

定义:

1~n中与n互质的数的个数称为欧拉函数,记为 φ ( n ) \varphi(n) φ(n)
φ ( 1 ) = 1 \varphi(1)=1 φ(1)=1
φ ( 2 ) = 1 \varphi(2)=1 φ(2)=1
φ ( 3 ) = 2 \varphi(3)=2 φ(3)=2

性质:

1、若p是质数, φ ( p ) \varphi(p) φ(p)=p-1

2、若p是质数, φ ( p k ) \varphi(p^{k}) φ(pk)= p k − 1 ∗ ( p − 1 ) p^{k-1}*(p-1) pk−1∗(p−1)

性质二解释:
1 , . . . , p , . . . , 2 ∗ p , . . . . . . , p k 1,...,p,...,2*p,......,p^{k} 1,...,p,...,2∗p,......,pk

可以将它们分段处理:

1,...,p\],\[p+1,...,2\*p\],... 可以发现每一段的大小都是p,所以会有 p k / p p\^{k}/p pk/p段,每一段都有(p-1)个,所以答案就是上述的描述 3、积性函数:若gcd(m,n)=1,则 φ ( m n ) = φ ( m ) ∗ φ ( n ) \\varphi(mn)=\\varphi(m)\*\\varphi(n) φ(mn)=φ(m)∗φ(n) ### 计算公式: ![请添加图片描述](https://i-blog.csdnimg.cn/direct/c676f9026b00436bae4d8e9b60d71047.jpeg) ### 总结: 根据推导的公式可以得出欧拉函数只与n和其1\~n之间的质数有关 ### 代码: ```cpp #include #define int long long #define ull unsigned long long using namespace std; const int N=2e5+10; int primes[N],cnt=0; bool vis[N]; int phi[N]; void init(){ phi[1]=1; for(int i=2;i>n; for(int i=1;i<=n;i++)cout<>_; while(_--)solve(); } ``` ## 欧拉反演 ### 定义: 对于任意的正整数n有: ∑ d ∣ n ϕ ( d ) = n \\sum_{d \\mid n}\\phi(d)=n ∑d∣nϕ(d)=n n的所有的因数(包含1和n本身)的欧拉函数之和等于n ### 证明: ![请添加图片描述](https://i-blog.csdnimg.cn/direct/f0db1687149646dabe4d4c88ad69dce3.jpeg) ### 应用: 求解 ∑ i = 1 n g c d ( i , n ) \\sum_{i=1}\^{n}gcd(i,n) ∑i=1ngcd(i,n)的时候可以优化,步骤如下: g c d ( i , n ) = ∑ d ∣ g c d ( i , n ) ϕ ( d ) gcd(i,n)=\\sum_{d\|gcd(i,n)}\\phi(d) gcd(i,n)=∑d∣gcd(i,n)ϕ(d) ![请添加图片描述](https://i-blog.csdnimg.cn/direct/84bc8b6f6ad14a748b341ea350179dd2.jpeg) ### 例题: ### 题目思路: ![请添加图片描述](https://i-blog.csdnimg.cn/direct/7539cef004bd4fba8c668cb84f44c37c.jpeg) ### 代码: ```cpp #include #define int long long #define ull unsigned long long using namespace std; const int N=2e5+10; int primes[N],cnt=0; bool vis[N]; int phi[N]; void init(){ phi[1]=1; for(int i=2;i>n; vectora(n+1); for(int i=1;i<=n;i++)cin>>a[i]; sort(a.begin()+1,a.end()); vectorcnt(N); int sum=0; for(int i=1;i<=n;i++){ for(int j=1;j*j<=a[i];j++){ if(a[i]%j==0){ sum+=(n-i)*phi[j]*cnt[j]; cnt[j]++; if(j*j!=a[i]){ sum+=(n-i)*phi[a[i]/j]*cnt[a[i]/j]; cnt[a[i]/j]++; } } } } cout<>_; while(_--)solve(); } ```

相关推荐
源代码•宸4 分钟前
Golang原理剖析(Map 源码梳理)
经验分享·后端·算法·leetcode·golang·map
Narrastory9 分钟前
手把手实现蚁群算法:从数学原理到代码实践
算法
mit6.82419 分钟前
八皇后变题hash|网格dp
算法
bybitq26 分钟前
LeetCode-437-路径总和3
算法
鱼跃鹰飞1 小时前
Leetcode尊享面试100题:1060. 有序数组中的缺失元素
算法·leetcode·面试
啊我不会诶1 小时前
AtCoder Beginner Contest 438 vp补题
算法
computersciencer1 小时前
用最小二乘法求解一元一次方程模型的参数
算法·机器学习·最小二乘法
mit6.8241 小时前
扫描线|离散化|seg+二分|卡常
算法
不穿格子的程序员1 小时前
从零开始写算法——二叉树篇6:二叉树的右视图 + 二叉树展开为链表
java·算法·链表
大志若愚YYZ2 小时前
ROS2学习 C++中的this指针
c++·学习·算法