Part. 1 Preface

这个东西是我在做 JZPTAB 的时候 LYC 给我讲的。

然后发现这是个通法,就写一写。

本文除了例题所有代码均未经过编译,仅作为参考。

Part. 2 Untitled(怎么取标题呀)(哦 正文)

Part. 2-1 Worse ver.

对于一个积性函数 \(f(n)\),如果我们已知 \(f(1),f(p),f(p^{k})\) (\(p\) 是一个素数)并且可以在 \(O(\log_{2}(n))\) 的时间内算出来的话,我们就可以在 \(O(n\log_{2}(n))\) 的时间内利用 Euler 筛筛出 \(f(1\cdots n)\) 的值。

举个例子,假设

\[f(n)=\sum_{d|n}d\times\varphi(\lfloor\frac{n}{d}\rfloor)
\]

由于 \(\text{id}\) 卷 \(\varphi\) 卷不出个什么现成的函数,所以我们得考虑自己把它筛出来。

带个 \(p\) 进去可知

\[\begin{cases}
f(1)=1 \\
\displaystyle
f(p)=2\times p-1 \\
\displaystyle
f(p^{k})=(k+1)\times p^{k}-k\times p^{k-1}
\end{cases}
\]

以下内容请参考 Euler 筛代码来看:

void sieve ( const int x ) {
tag[1] = 1, f[1] = /* DO SOMETHING 1 */;
for ( int i = 2; i <= x; ++ i ) {
if ( ! tag[i] ) {
pSet[++ psc] = i;
f[i] = /* DO SOMETHING 2 */;
}
for ( int j = 1; j <= psc && pSet[j] * i <= x; ++ j ) {
tag[pSet[j] * i] = 1;
if ( ! ( i % pSet[j] ) ) {
f[pSet[j] * i] = /* DO SOMETHING 3 */;
break;
}
else f[pSet[j] * i] = /* DO SOMETHING */;
}
}
}

函数 \(\text{sieve}\) 就是 Euler 筛的过程。我在代码中留了四个空,分别来看我们需要做什么。

  • 第一个空很显然,把 \(f(1)\) 赋给 f[1] 即可。

  • 第二个空也很显,把 \(f(p)\) 付给 f[i]

  • 我们重点来看第三个空。

首先因为此时的 \(i,\text{pSet}_{j}\) 不互质,所以不能直接照完全积性函数筛。

首先,我们需要把 \(i\times\text{pSet}_{j}\) 中 \(\text{pSet}_{j}\) 因子全部除掉,除完后的结果记为 \(\text{tmp}\),\(\text{pSet}_{j}\) 因子数量记为 \(\text{power}\),即 \(i\times\text{pSet}_{j}=\text{pSet}_{j}^{\text{power}}\times c\)。

就是类似下面代码做的事情

int tmp = i / pSet[j], power = 2;
while ( ! ( i % pSet[j] ) ) i /= pSet[j], ++ power;

然后对 \(\text{tmp}\) 进行分类讨论:

    • \(\text{tmp}=1\):此时 \(i\times\text{pSet}_{j}\) 是 \(\text{pSet}_{j}\) 的 \(\text{power}\) 次方,把 \(f(p^{k})\) 赋给 f[pSet[j] * i] 即可。
    • \(\text{tmp}>1\):此时 \(\text{tmp}\) 与 \(\frac{i\times\text{pSet}_{j}}{\text{tmp}}\) 互质,于是照积性函数 f[pSet[j] * i] = f[pSet[j] * i / tmp] * f[tmp]

于是第三个空做完了。

  • 第四个空中 \(\text{pSet}_{j}\) 与 \(i\) 互质,于是照积性函数 f[pSet[j] * i] = f[pSet[j]] * f[i]

于是我们得到了完整代码

void sieve ( const int x ) {
tag[1] = 1, f[1] = 1;
for ( int i = 2; i <= x; ++ i ) {
if ( ! tag[i] ) {
pSet[++ psc] = i;
f[i] = 2 * i - 1;
}
for ( int j = 1; j <= psc && pSet[j] * i <= x; ++ j ) {
tag[pSet[j] * i] = 1;
if ( ! ( i % pSet[j] ) ) {
int tmp = i / pSet[j], power = 2;
while ( ! ( i % pSet[j] ) ) i /= pSet[j], ++ power;
if ( tmp == 1 ) f[pSet[j] * i] = ( power + 1 ) * cqpow ( pSet[j], power ) - power * cqpow ( pSet[j], power - 1 );
else f[pSet[j] * i] = f[pSet[j] * i / tmp] * f[tmp];
break;
}
else f[pSet[j] * i] = f[pSet[j]] * f[i];
}
}
}

Part. 2-2 Better ver.

上述的方法的缺点显而易见:复杂度多出来个 \(\log_{2}\)。

更好的方法是记录最小质因子,具体见 ljs 博客 Link

Part. 3 Example

LOCAL 64388 - GCD SUM

\[\sum_{i=1}^n\sum_{j=1}^m\textrm{gcd}(i,j)
\]

共有 \(T\) 组询问

\(\text{task_id}\) 测试点数 \(n,m\leq\) \(T\leq\) 特殊性质
\(1\) 1 \(10\) \(10^3\)
\(2\) 2 \(10^3\) \(10\)
\(3\) 3 \(10^3\) \(10^4\)
\(4\) 4 \(10^6\) \(10\) \(n = m\)
\(5\) 5 \(10^6\) \(10^4\) \(n = m\)
\(6\) 2 \(10^6\) \(10^5\) \(n = m\)
\(7\) 3 \(10^7\) \(10^6\) \(n = m\)
\(8\) 2 \(10^6\) \(10\)
\(9\) 3 \(10^6\) \(10^4\)

放个 task 7 以外的部分分的推导

\[\sum_{i=1}^{n}\sum_{j=1}^{m}\gcd(i,j) \\
\begin{aligned}
&=\sum_{d=1}^{\min\{n,m\}}d\sum_{i=1}^{n}\sum_{j=1}^{m}[\gcd(i,j)=d] \\
&=\sum_{d=1}^{\min\{n,m\}}d\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}[\gcd(i,j)=1] \\
&=\sum_{d=1}^{\min\{n,m\}}d\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}\sum_{k|i,k|j}\mu(k) \\
&=\sum_{d=1}^{\min\{n,m\}}d\sum_{k|(\lfloor\frac{n}{d}\rfloor),k|(\lfloor\frac{m}{d}\rfloor)}\mu(k)(\lfloor\frac{n}{d\times k}\rfloor)(\lfloor\frac{m}{d\times k}\rfloor) \\
&=\sum_{d=1}^{\min\{n,m\}}d\sum_{k|(\lfloor\frac{n}{d}\rfloor),k|(\lfloor\frac{m}{d}\rfloor)}\mu(k)(\lfloor\frac{n}{d\times k}\rfloor)(\lfloor\frac{m}{d\times k}\rfloor) \\
&=\sum_{T=1}^{\min\{n,m\}}\sum_{d|T}d\times\mu(\lfloor\frac{T}{d}\rfloor)\times(\lfloor\frac{n}{T}\rfloor)\times(\lfloor\frac{m}{T}\rfloor) \\
&=\sum_{T=1}^{\min\{n,m\}}(\lfloor\frac{n}{T}\rfloor)\times(\lfloor\frac{m}{T}\rfloor)\times\sum_{d|T}d\times\mu(\lfloor\frac{T}{d}\rfloor) \\
&=\sum_{T=1}^{n}(\lfloor\frac{n}{T}\rfloor)^{2}\times\varphi(T) \\
\end{aligned}
\]

对于 task 7,\(n=m\) 让我们很方便地直接少了一个变量,然后就继续推

\[\sum_{i=1}^{n}\sum_{j=1}^{n}\gcd(i,j) \\
\begin{aligned}
&=\left(2\sum_{i=1}^{n}\sum_{j=1}^{i}\gcd(i,j)\right)-\frac{n(n+1)}{2} \\
&=\left(2\sum_{i=1}^{n}\sum_{d|i}d\times\sum_{j=1}^{i}[\gcd(i,j)=d]\right)-\frac{n(n+1)}{2} \\
&=\left(2\sum_{i=1}^{n}\sum_{d|i}d\times\sum_{j=1}^{\lfloor\frac{i}{d}\rfloor}[\gcd(\lfloor\frac{i}{d}\rfloor,j)=1]\right)-\frac{n(n+1)}{2} \\
&=\left(2\sum_{i=1}^{n}\sum_{d|i}d\times\varphi(\lfloor\frac{i}{d}\rfloor)\right)-\frac{n(n+1)}{2} \\
\end{aligned}
\]

然后

\[\text{let }f(n)=\sum_{d|n}d\times\varphi(\lfloor\frac{n}{d}\rfloor)
\]

后面的就是前面举的例子了,略。

/*
\large\text{For 1e6 part} \\
\sum_{i=1}^{n}\sum_{j=1}^{m}\gcd(i,j) \\
\sum_{d=1}^{\min(n,m)}d\sum_{i=1}^{n}\sum_{j=1}^{m}[\gcd(i,j)=d] \\
\sum_{d=1}^{\min(n,m)}d\sum_{i=1}^{n/d}\sum_{j=1}^{m/d}[\gcd(i,j)=1] \\
\sum_{d=1}^{\min(n,m)}d\sum_{i=1}^{n/d}\sum_{j=1}^{m/d}\sum_{k|i,k|j}\mu(k) \\
\sum_{d=1}^{\min(n,m)}d\sum_{k|(n/d),k|(m/d)}\mu(k)(n/(dk))(m/(dk)) \\
\sum_{d=1}^{\min(n,m)}d\sum_{k|(n/d),k|(m/d)}\mu(k)(n/(dk))(m/(dk)) \\
\sum_{T=1}^{\min(n,m)}\sum_{d|T}d\times\mu(T/d)\times(n/T)\times(m/T) \\
\sum_{T=1}^{\min(n,m)}(n/T)\times(m/T)\times\sum_{d|T}d\times\mu(T/d) \\
\sum_{T=1}^{n}(n/T)^{2}\times\varphi(T) \\
\text{precalculate the last part} \\
\large\text{For 1e7 part} \\
n=m \\
\left(2\sum_{i=1}^{n}\sum_{j=1}^{i}\gcd(i,j)\right)-\frac{n(n+1)}{2} \\
\left(2\sum_{i=1}^{n}\sum_{d|i}d\times\sum_{j=1}^{i}[\gcd(i,j)=d]\right)-\frac{n(n+1)}{2} \\
\left(2\sum_{i=1}^{n}\sum_{d|i}d\times\sum_{j=1}^{i/d}[\gcd(i/d,j)=1]\right)-\frac{n(n+1)}{2} \\
\left(2\sum_{i=1}^{n}\sum_{d|i}d\times\varphi(i/d)\right)-\frac{n(n+1)}{2} \\
f(i)=\sum_{d|i}d\times\varphi(i/d) \\
\text{f(i) is able to be sieved;} \\
f(1)=1,f(p)=p-1+p=2\times p-1,f(p^{k})=(k+1)\times p^{k}-k\times p^{k-1}
*/
#include<cstdio>
#include<algorithm>
using namespace std;
int id,t,n,m,tag[10000010],prime[10000010],cnt;
long long f[10000010],phi[10000010];
long long cqpow(long long bas,int fur)
{
long long res=1;
while(fur)
{
if(fur&1) res*=bas;
bas*=bas;
fur>>=1;
}
return res;
}
void search(int x)
{
tag[1]=phi[1]=1;
for(int i=2;i<=x;++i)
{
if(!tag[i])
{
prime[++cnt]=i;
phi[i]=i-1;
}
for(int j=1;j<=cnt&&(long long)prime[j]*i<=x;++j)
{
tag[prime[j]*i]=1;
if(i%prime[j]==0)
{
phi[prime[j]*i]=phi[i]*prime[j];
break;
}
else phi[prime[j]*i]=phi[i]*(prime[j]-1);
}
}
for(int i=1;i<=x;++i) phi[i]+=phi[i-1];
}
long long calc(int x,int y)
{
long long res=0;
int lim=min(x,y);
for(int l=1,r;l<=lim;l=r+1)
{
r=min(x/(x/l),y/(y/l));
res+=(long long)(n/l)*(m/l)*(phi[r]-phi[l-1]);
}
return res;
}
void exsearch(int x)
{
tag[1]=f[1]=1;
for(int i=2;i<=x;++i)
{
if(!tag[i])
{
prime[++cnt]=i;
f[i]=(i<<1)-1;
}
for(int j=1;j<=cnt&&(long long)prime[j]*i<=x;++j)
{
tag[prime[j]*i]=1;
if(i%prime[j]==0)
{
int tmp=i/prime[j],power=2;
while(tmp%prime[j]==0)
{
tmp/=prime[j];
power++;
}
if(tmp==1) f[prime[j]*i]=(power+1)*cqpow(prime[j],power)-power*cqpow(prime[j],power-1);
else f[prime[j]*i]=f[prime[j]*i/tmp]*f[tmp];
break;
}
else f[prime[j]*i]=f[prime[j]]*f[i];
}
}
for(int i=1;i<=x;++i) f[i]+=f[i-1];
}
long long excalc(long long x)
{
return (f[x]<<1)-((x*(x+1))>>1);
}
int main()
{
scanf("%d%d",&id,&t);
if(id^7)
{
search(1000000);
while(t--)
{
scanf("%d%d",&n,&m);
printf("%lld\n",calc(n,m));
}
}
else
{
exsearch(10000000);
while(t--)
{
scanf("%d%d",&n,&m);
printf("%lld\n",excalc(n));
}
}
return 0;
}

Note -「Maths」Euler 筛筛积性函数的更多相关文章

  1. P6222 「简单题」加强版 莫比乌斯反演 线性筛积性函数

    LINK:简单题 以前写过弱化版的 不过那个实现过于垃圾 少预处理了一个东西. 这里写一个实现比较精细了. 最后可推出式子:\(\sum_{T=1}^nsum(\frac{n}{T})\sum_{x| ...

  2. hdu2421-Deciphering Password-(欧拉筛+唯一分解定理+积性函数+立方求和公式)

    Deciphering Password Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  3. Mobius反演与积性函数前缀和演学习笔记 BZOJ 4176 Lucas的数论 SDOI 2015 约数个数和

    下文中所有讨论都在数论函数范围内开展. 数论函数指的是定义域为正整数域, 且值域为复数域的函数. 数论意义下的和式处理技巧 因子 \[ \sum_{d | n} a_d = \sum_{d | n} ...

  4. 积性函数&线性筛&欧拉函数&莫比乌斯函数&因数个数&约数个数和

    只会搬运YL巨巨的博客 积性函数 定义 积性函数:对于任意互质的整数a和b有性质f(ab)=f(a)f(b)的数论函数. 完全积性函数:对于任意整数a和b有性质f(ab)=f(a)f(b)的数论函数 ...

  5. ACM-ICPC 2018 南京赛区网络预赛Sum,线性筛处理积性函数

    SUM 题意:f(n)是n可以拆成多少组n=a*b,a和b都是不包含平方因子的方案数目,对于a!=b,n=a*b和n=b*a算两种方案,求∑i=1nf(i) 首先我们可以知道,n=1时f(1)=1, ...

  6. 莫比乌斯反演/线性筛/积性函数/杜教筛/min25筛 学习笔记

    最近重新系统地学了下这几个知识点,以前没发现他们的联系,这次总结一下. 莫比乌斯反演入门:https://blog.csdn.net/litble/article/details/72804050 线 ...

  7. bzoj2693--莫比乌斯反演+积性函数线性筛

    推导: 设d=gcd(i,j) 利用莫比乌斯函数的性质 令sum(x,y)=(x*(x+1)/2)*(y*(y+1)/2) 令T=d*t 设f(T)= T可以分块.又由于μ是积性函数,积性函数的约束和 ...

  8. hdu1452 Happy 2004(规律+因子和+积性函数)

    Happy 2004 题意:s为2004^x的因子和,求s%29.     (题于文末) 知识点: 素因子分解:n = p1 ^ e1 * p2 ^ e2 *..........*pn ^ en 因子 ...

  9. HDU 1452 Happy 2004 (逆元+快速幂+积性函数)

    G - Happy 2004 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Subm ...

  10. spoj 3871. GCD Extreme 欧拉+积性函数

    3871. GCD Extreme Problem code: GCDEX Given the value of N, you will have to find the value of G. Th ...

随机推荐

  1. Hive执行计划之一文读懂Hive执行计划

    目录 概述 1.hive执行计划的查看 2.学会查看Hive执行计划的基本信息 3.执行计划步骤操作过程 4.explain extended 概述 Hive的执行计划描述了一个hiveSQL语句的具 ...

  2. 20.AQS家族的“外门弟子”:CyclicBarrier

    关注王有志,一个分享硬核Java技术的互金摸鱼侠 欢迎你加入Java人的提桶跑路群:共同富裕的Java人 今天我们来学习AQS家族的"外门弟子":CyclicBarrier. 为什 ...

  3. 搭建自动化 Web 页面性能检测系统 —— 实现篇

    我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品.我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值.. 本文作者:琉易 liuxianyu.cn 前段时间分享了<搭 ...

  4. SLF4J门面日志框架源码探索

    1 SLF4J介绍 SLF4J即Simple Logging Facade for Java,它提供了Java中所有日志框架的简单外观或抽象.因此,它使用户能够使用单个依赖项处理任何日志框架,例如:L ...

  5. C++面试八股文:std::vector和std::list,如何选择?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第24面: 面试官:list用过吗? 二师兄:嗯,用过. 面试官:请讲一下list的实现原理. 二师兄:std::list被称为双向链表,和C中手写双 ...

  6. C# - DTO 的字符串表达

    第一阶段 重写 DTO 的 ToString() 方法.利用 Newtonsoft.Json 序列化 DTO 对象. 第二阶段 为 DTO 设置基类,重写基类的 ToString() 方法.利用 Sy ...

  7. allure报告生成

    allure生成测试报告 ‍1.生成xml文件 pytest 测试文件所在路径 --alluredir 生成的测试结果数据保存的目录 pytest --alluredir=resport/xml/ D ...

  8. JavaScript中this的绑定

    <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> <path s ...

  9. 打开页面就能玩?ZEGO 发布行业首套 Web 端在线 KTV 解决方案

    近些年,在线K歌行业逐渐开始规模化发展,活跃用户不断破新高,据 ZEGO 即构科技研究院数据显示,2021 年中国在线 K 歌用户规模逾 5.2亿,网民渗透率达到 50%. 凭借着极大的便利性和娱乐性 ...

  10. 巧用 nc 命令传输文件

    今天在业务上云的时候,遇到了些问题.最终发现问题的根源不好排查,于是-- 把生产环境的全量配置文件,还有日志全量打包下载到开发机器分析! 刚入职不是很久的整个运维团队,也不是很熟悉生产环境(有时候觉得 ...