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

欧拉函数

定义:

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(); } ```

相关推荐
45288655上山打老虎1 小时前
右值引用和移动语义
算法
liulilittle1 小时前
C++ 并发双阶段队列设计原理与实现
linux·开发语言·c++·windows·算法·线程·并发
白狐_7982 小时前
【项目实战】我用一个 HTML 文件写了一个“CET-6 单词斩”
前端·算法·html
Jasmine_llq2 小时前
《P3811 【模板】模意义下的乘法逆元》
数据结构·算法·线性求逆元算法·递推求模逆元
Jacob程序员2 小时前
欧几里得距离算法-相似度
开发语言·python·算法
ffcf2 小时前
消息中间件6:Redis副本数变为0和删除PVC的区别
算法·贪心算法
CoderYanger2 小时前
动态规划算法-斐波那契数列模型:2.三步问题
开发语言·算法·leetcode·面试·职场和发展·动态规划·1024程序员节
sin_hielo2 小时前
leetcode 2211
数据结构·算法·leetcode
CoderYanger3 小时前
动态规划算法-简单多状态dp问题:16.买卖股票的最佳时机含手续费
开发语言·算法·leetcode·动态规划·1024程序员节