PE512Sums of totients of powers(欧拉函数)
Posted chenxiaoran666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PE512Sums of totients of powers(欧拉函数)相关的知识,希望对你有一定的参考价值。
大致题意: 求\(\sum_n=1^5*10^8((\sum_i=1^n\phi(n^i))(mod\ n+1))\)。
大力推式子
单独考虑\((\sum_i=1^n\phi(n^i))(mod\ n+1)\)。
由于\(\phi\)有一个显然的性质:
\[\phi(x^y)=\phi(x)\cdot x^y-1\]
所以上面的式子就可以推成:
\[(\phi(n)\sum_i=1^nn^i-1)(mod\ n+1)\]
又由于\(n\equiv-1(mod\ n+1)\),所以上式即为:
\[(\phi(n)\sum_i=1^n(-1)^i-1)(mod\ n+1)\]
观察\(\sum_i=1^n(-1)^i-1\)可知,这个式子在\(n\)为奇数时为\(1\),\(n\)为偶数时为\(0\)。
而显然\(\phi(n)<n<n+1\),所以最后我们要求的就是\(1\sim5*10^8\)内所有奇数的\(\phi\)值之和。
注意开数组
注意到一点,\(5*10^8\)的数组即使在本地也是开不下的。
怎么办?杜教筛。
好吧,实际上可以不用杜教筛。
考虑到我们只需要奇数的\(\phi\)值,而\(\phi\)是一个积性函数,显然我们不可能从偶数的\(\phi\)值转移得出奇数的\(\phi\)值,因此筛偶数是不必要的。
这样一来,对于一个奇数\(x\),我们用数组第\(\fracx+12\)位去存储它,就实现了数组大小减半,开得下了。
代码
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 500000000
#define LL long long
using namespace std;
class LinearSiever//线性筛
private:
#define LS 250000000
#define PS 15000000
int Pt,P[PS+5];bool vis[LS+5];
public:
int phi[LS+5];//存储phi值
I void Sieve(CI S)
RI i,j;for(phi[1]=1,i=3;i<=S;i+=2)//与普通线性筛几乎无异,但注意下标变化
!vis[i+1>>1]&&(P[++Pt]=i,phi[i+1>>1]=i-1);
for(j=1;j<=Pt&&1LL*i*P[j]<=S;++j)
if(vis[i*P[j]+1>>1]=1,i%P[j]) phi[i*P[j]+1>>1]=phi[i+1>>1]*(P[j]-1);
else phi[i*P[j]+1>>1]=phi[i+1>>1]*P[j];break;
L;
int main()
RI i;LL ans=0;for(L.Sieve(N),i=1;i<=(N+1>>1);++i) ans+=L.phi[i];//统计答案
return printf("%lld",ans),0;//输出答案
运行结果
50660591862310323
以上是关于PE512Sums of totients of powers(欧拉函数)的主要内容,如果未能解决你的问题,请参考以下文章
[codeforces 509]C. Sums of Digits
CodeForces - 1618A Polycarp and Sums of Subsequences
CodeForces - 1618A Polycarp and Sums of Subsequences
CF1303G Sum of Prefix Sums[李超树,点分治]