一类欧拉函数相关的求和式推导

\(\\\)

写在前面



因为最近做了不少和欧拉函数相关的求和问题,而这一类求和的推导有没有涉及到反演和卷积,所以单独写一写。

给出的题目顺序与难度大致无关,是按照个人做题的顺序安排的。

再次声明欧拉函数的定义:\(\varphi(x)\) 表示 \([1,x]\) 里的所有整数中,与 \(x\) 互质的数的个数。

下面的叙述中均用 \((x,y)\) 表示 \(gcd(x,y)\) ,用 \([x,y]\) 表示 \(lcm(x,y)\) 。

\(\\\)

欧拉函数的两种常用求法


  • 公式法,单点复杂度 \(\sqrt n\) ,常用于少量求函数值

    将 \(n\) 质因数分解为 \(n=p_1^{k_1}\times p_2^{k_2}\times...\times p_m^{k_m}\)。

    那么有 \(\varphi(n)=n\times \frac{p_1-1}{p_1}\times \frac{p_2-1}{p_2}\times ...\times\frac{p_m-1}{p_m}\) ,复杂度显然是质因数分解复杂度。

    注意复杂度分析的时候不能直接是 个数\(\times \sqrt n\) ,因为往往我们求的数并不全都是卡上限的。

  • 线性筛,复杂度线性,用于求一个不大的数域内全部的函数值。

\(\\\)

[ SDOI 2012 ] Longge的问题



给出一个 \(n\) ,求
\[
\sum_{i=1}^n\ (i,n)
\]

  • \(n\le 2^{32}\)

注意到数据范围非常大,这一类数据量我们通常考虑 \(\sqrt n\) 级别的做法。

首先有两个显然的性质:

  • 任意两数的最大公约数首先要是这两个数各自的约数,所以 \((i,n)\) 首先是 \(n\) 的约数
  • 任何一个数的约数是成对存在的,这也是试除法成立的前提

然后根据经典的做法,我们通常将相同的 \(gcd\) 提出来,对每一个因数考虑它被计算的次数,有
\[
\sum_{i=1}^n\ (i,n)=\sum_{d=1,d|n}^n \bigg(d\times \sum_{i=1}^n\ [(i,n)=d]\bigg)=\sum_{d=1,d|n}^n \bigg(d\times \sum_{i=1}^n\ [(\frac id,\frac nd)=1]\bigg)
\]
然后按照经典的做法我们把变量上限改一下,得到
\[
\sum_{d=1,d|n}^n \bigg(d\times \sum_{i=1}^n\ [(\frac id,\frac nd)=1]\bigg)=\sum_{d=1,d|n}^n \bigg(d\times \sum_{i=1}^\frac nd\ [(i,\frac nd)=1]\bigg)=\sum_{d=1,d|n}^n \bigg(d\times \varphi(\frac nd)\bigg)
\]
然后试除法求 \(n\) 的所有约数,单点求一下 \(\varphi\) 即可。

\(\\\)

[ SDOI 2008 ] 仪仗队



给出一个 \(n\) ,求
\[
\sum_{i=1}^n\sum_{j=1}^n\ [(i,j)=1]
\]

  • \(n\le 4\times 10^4\)

\(\\\)

考虑这是求一个\(n\times n\)的矩阵内,横纵坐标互质的点的个数。

先考虑纵坐标小于横坐标的情况,那么相当于求每一个横坐标有多少个小于其且与其互质的纵坐标,有
\[
\sum_{i=1}^n \sum_{j=1}^i\ [(i,j)=1]=\sum_{i=1}^n\varphi(i)
\]
那么剩余的部分显然是纵坐标大于横坐标的点,考虑将横纵坐标交换,有转化成了刚才的式子。

此时我们对角线上的点都被重算了一次,但是除了 \((1,1)\) 点以外所有对角线上的点显然横纵坐标并不互质
\[
ans=\bigg(\sum_{i=1}^n \varphi(i)\bigg)\times 2-1
\]

\(\\\)

[ BZOJ 2818 ] GCD



给出一个 \(n\) ,求
\[
\sum_{i=1}^n\sum_{j=1}^n\ [(i,j)\ is\ prime]
\]

  • \(n\le 10^7\)

按照经典的做法我们先枚举 \(gcd\) 的值,式子变成
\[
\sum_{d=1,\ d\ is\ prime}^n\sum_{i=1}^n\sum_{j=1}^n\ [(i,j)=d]=\sum_d\sum_{i=1}^{\lfloor\frac nd\rfloor}\sum_{j=1}^{\lfloor\frac nd\rfloor}\ [(i,j)=1]
\]
发现后面的两个求和号就变成了上一题。

线性处理欧拉函数,线性求前缀和,再枚举 \(n\) 以内的质数,累加上其对应的答案就好。

\(\\\)

[ Luogu 2398 ] GCD SUM



给出一个 \(n\) ,求
\[
\sum_{i=1}^n\sum_{j=1}^n\ (i,j)
\]

  • \(n\le 10^5\)

按照套路我们枚举 \((i,j)\) 是啥,放到式子的最前面,有
\[
\sum_{d=1}^nd\times\sum_{i=1}^n\sum_{j=1}^n\ [(i,j)=d]=\sum_{d=1}^nd\times \sum_{i=1}^{\lfloor\frac nd\rfloor}\sum_{j=1}^{\lfloor\frac nd\rfloor}\ [(i,j)=1]
\]
然后后面的就是仪仗队这个题了,最后线性扫几遍就能得到答案。

\(\\\)

[ Uva 11426 / 11424 / 11417 / SPOJ 3871 ] GCD Extreme



给出\(T\)个 \(n\) ,对每一个 \(n\) 求
\[
\sum_{i=1}^n\sum_{j=i+1}^n\ (i,j)
\]

  • \(n\le 4\times10^6,T\le 2\times 10^4\)

这题邪死我了.......

开始的想法是错误的,想到了按照上一个题那样把 \(d\) 提出来放到前面,然后发现多组询问复杂度是
\[
\text O(N+T\sqrt N)\ /\ \text O(N\sqrt N+T)
\]
并不优秀,具体实现的话是对询问的数字单独除法分块。

不妨分析一下式子换一个角度。假入我们还是把问题放在一个\(n\times n\) 的矩阵上,那么求的其实是直线 \(y=x\) 以上的所有整点里,横纵坐标互质的点数。这个数目显然是与直线 \(y=x\) 一下的横纵坐标互质的点数个数是相等的。

然后所求就转化为
\[
\sum_{i=1}^n\sum_{j=1}^{i-1} (i,j)
\]
我们设
\[
g[x]=\sum_{i=1}^{x-1}(i,x)=\sum_{d=1,d|x}^{x-1}\bigg(d\times\sum_{i=1}^{x-1}\ [(i,x)=d]\bigg)=\sum_{d=1,d|x}^{x-1} \bigg(d\times \varphi(\frac nd)\bigg)
\]
答案就变成
\[
\sum_{i=1}^n g[i]
\]
显然这个求和是线性的,有了这个回答就是 \(\text O(1)\) 的。

然后就只需要考虑 \(g[x]\) 的求法。

其实也可以像 天守阁的地板 那道题一样用调和级数复杂度去做。

但是注意到每个数不计算自己作为 \(gcd\) 的贡献,所以我们枚举倍数的时候直接从 \(2\) 倍开始就可以了。

for(R int i=1;i<N;++i)
    for(R int j=i*2;j<N;j+=i) ans[j]+=(ll)i*phi[j/i];
  for(R int i=1;i<=N;++i) ans[i]+=ans[i-1];

\(\\\)

[ Luogu 1390 ] 公约数的和



给出一个 \(n\) ,求这\(n\)个数中每任意两个不同的数的最大公约数的和。

  • \(n\le 2\times10^6\)

稍微写写画画发现就是上面那道题....甚至只有一个询问。

还有一种解法就是 GCD SUM 那道题的答案减掉 \(1....n\) 之后除以 \(2\) 。

\(\\\)

[ Luogu 3601 ] 签到题



定义函数 \(f(x)\) 为小于等于 \(x\) 的数中与 \(x\) 不互质的数的个数。

给出 \(l,r\) ,求
\[
\sum_{i=l}^r f(i)\%66623333
\]

  • \(0\le l\le r\le 10^{12},r-l\le10^6\)

幌子比较明显......显然 \(f(x)=x-\varphi(x)\) 然后就是两个求和减一下,前面是等差数列,我们只关心后一个。


\[
\sum_{i=l}^r \varphi(i)
\]
显然线性筛不能筛这么大数据范围,所以需要单点求欧拉函数值。

考虑对每一个数质因数分解复杂度还是过高,所以考虑每一个因数的影响。

显然区间里的 \(x\) 的倍数只有 \(\frac{len}{x}\) 个,所以复杂度调和级数,枚举倍数然后更新一下就好了。

最后判断一下区间里的每一个数是否变成 \(1\) 了,若没有就再算一次即可。

for(R ll i=1;i<=prm[0];++i){
    ll val=prm[i];
    for(R ll j=(val-l%val)%val;j<=r-l;j+=val){
        phi[j]=(phi[j]/val)*(val-1);
        while(fac[j]%val==0) fac[j]/=val;
    }
}

\(\\\)

[ SPOJ 5971 ] LCMSUM



\(T\)组数据,每组给出一个 \(n\) ,求
\[
\sum_{i=1}^n\ [i,n]
\]

  • \(T\le3\times 10^5,n\le 10^6\)

看这么彪悍的数据范围....别想了 \(O(1)\) 回答吧。
\[
\sum_{i=1}^n\ [i,n]=\sum_{i=1}^n \frac{i\times n}{(i,n)}=n\times\sum_{i=1}^n \frac{i}{(i,n)}
\]
然后我们就只关心后面这个求和了。照例把 \(gcd\) 枚举一下
\[
\sum_{i=1}^n \frac{i}{(i,n)}=\sum_{d=1,d|n}^n \sum_{i=1}^n \frac id[(i,n)=d]=\sum_{d=1,d|n}^n \sum_{i=1}^{\frac nd} i\ [(i,\frac nd)=1]
\]
第二个等号就是把限制条件扔到了求和上限上,注意求和的对象也在变。

然后我们知道,\(d\) 和 \(\frac nd\) 是成对出现的,所以可以把 \(\frac nd\) 替换一下
\[
\sum_{d=1,d|n}^n \sum_{i=1}^{\frac nd} i\ [(i,\frac nd)=1]=\sum_{d=1,d|n}^n \sum_{i=1}^d i\ [(i,d)=1]
\]
然后后面这个求和号就是与 \(d\) 互质的数的和对吧。

有一个神奇的等式
\[
\sum_{i=1}^n i\ [(i,n)=1]=\frac{\varphi(n)\times n}{2}
\]
证明是这样的:

如果存在一个与 \(n\) 互质的数 \(x\) ,那么 \(n-x\) 也与 \(n\) 互质,这由辗转相除法就可以得到。

然后由于与 \(n\) 互质的数一定不是 \(n\) 的约数,所以这样的数一定是按照上面的原则成对出现的。

每一对的和是 \(n\) ,一共有 \(\frac {\varphi(n)}2\) 对。

然后所求就化为
\[
\sum_{d=1,d|n}^n\frac{\varphi(d)\times d}{2}
\]
因为是要预处理所有的答案,就调和级数的做就好啦,每次枚举 \(x\) 的倍数,向倍数累加 \(\frac{\varphi(x)\times x}{2}\)。

原文地址:https://www.cnblogs.com/SGCollin/p/9909276.html

时间: 2024-08-09 03:33:49

一类欧拉函数相关的求和式推导的相关文章

数学 欧拉函数相关

欧拉函数相关 1,\(phi(i)\)表示在1到i的数中与i互质的数的个数. 2,\(O(\sqrt{n})\)求\(phi\) ? 算数基本定理: \[ phi(i)=i*(p_1-1)/p_1*(p_2-1)/p_2*--*(p_k-1)/p_k \] ? 枚举质因数套公式即可: ? code: int phi(int x){ int re=x; for(int i=2;i*i<=x;i++){ if(x%i==0){ re=re/i*(i-1); while(x%i==0)x/=i; }

HDOJ 3501 Calculation 2(欧拉函数拓展——求非互质数和)

Calculation 2 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2548    Accepted Submission(s): 1064 Problem Description Given a positive integer N, your task is to calculate the sum of the posit

欧拉线性筛法求素数(顺便实现欧拉函数的求值)

我们先来看一下最经典的埃拉特斯特尼筛法.时间复杂度为O(n loglog n) int ans[MAXN]; void Prime(int n) { int cnt=0; memset(prime,1,sizeof(prime)); prime[0]=prime[1]=0; for(int i=2;i<n;i++) { if(vis[i]) { ans[cnt++]=i;//保存素数 for(int j=i*i;j<n;j+=i)//i*i开始进行了稍微的优化 prime[j]=0;//不是素

O(n)求素数,求欧拉函数,求莫比乌斯函数,求对mod的逆元,各种求

筛素数 void shai() { no[1]=true;no[0]=true; for(int i=2;i<=r;i++) { if(!no[i]) p[++p[0]]=i; int j=1,t=i*p[1]; while(j<=p[0] && t<=r) { no[t]=true; if(i%p[j]==0) //每一个数字都有最小质因子.这里往后的数都会被筛过的,break break; t=i*p[++j]; } } } O(n)筛欧拉函数 void find()

欧拉函数相关的题目

POJ 1284 求原根个数: 即求 euler(euler(p)) = euler(p-1) 其中p为奇素数 又有 euler(x) = x*(1-1/p1)*...*(1-1/pk)  其中pk为x的质因数 #include <cstdio> #include <cstring> int all, p, ans, num[100000]; bool pd[100000]; int main() { pd[1] = 1; for(int i = 1; i < 100000;

欧拉函数,求素数

/*=======================================================*\ | 递推求欧拉函数phi(i) 欧拉函数\varphi(n)是小于或等于n的正整数中与n互质的数的数目 \*=======================================================*/ #define N 3000000 __int64 phi[N + 100]; void Euler() { int i, j; for(i = 1; i

欧拉线性筛 和 欧拉函数的求值

PS:求逆元的部分在文章最后...最好也看看前边的知识吧qwq 用筛法求素数的基本思想是:把从1开始的.某一范围内的正整数从小到大顺序排列, 1不是素数,首先把它筛掉.剩下的数中选择最小的数是素数,然后去掉它的倍数.依次类推,直到筛子为空时结束.(来自 百度百科) 一般的筛法(埃拉托斯特尼筛法)的效率是O(nlglgn),但出题人卡你可就凉了.. (就不介绍了(逃)) 下面我们来说O(n)的欧拉线性筛 埃筛之所以慢,是因为有些合数被重复筛除(如:6会被2和3重复筛) 但是欧拉筛保证 每一个数p,

欧拉筛素数+求欧拉函数

线性筛法 prime记录素数,num_prime素数下标 它们保证每个合数只会被它的最小质因数筛去 a[0]=a[1]=1; for(int i=2;i<=n;i++) { if(!a[i]) prime[num_prime++]=i; for(int j=0;j<num_prime&&i*prime[j]<=n;j++) { a[i*prime[j]]=1; if(!(i%prime[j])) break; } } } 欧拉函数 是 积性函数:对于任意互质的整数a和b有

线性筛法(欧拉筛法)求素数

时间复杂度O(n)当n比较大时欧拉筛法所用的时间比O(nloglogn)的算法的时间少的会越来越明显 为什么呢? 因为在欧拉筛法中,每一个合数只被访问并将其所对的f[]的值修改了一次. for(i = 2; i <= n; i++) { if(f[i] == 0) { p[++cnt] = i; } for(j = 1; j <= cnt; j++) { if(i * p[j] > n)break; f[i * p[j]] = 1; if(i % p[j] == 0)break; } }