整理的算法模板合集: ACM模板


目录

  • 一、莫比乌斯反演
  • 二、几个概念和定理
  • 三、两种形式的莫比乌斯反演证明
  • 四、POJ 3904 Sky Code(入门例题)

一、莫比乌斯反演

学习笔记,我是看这个博客入门的,讲的非常好,传送门,关键是给出了非常多的定理,好多是数论书上的权威概念。

我自己证明的照片在文末,有点乱

首先,莫比乌斯反演是什么?

第一种形式:

F(n)=∑d∣nf(d)=>f(n)=∑d∣nμ(d)F(nd)F(n)=\sum_{d|n}f(d)=>f(n)=\sum_{d|n}\mu(d)F(\frac{n}{d})F(n)=d∣n∑​f(d)=>f(n)=d∣n∑​μ(d)F(dn​)
第二种形式:

F(n)=∑n∣df(d)=>f(n)=∑n∣dμ(dn)F(d)F(n)=\sum_{n|d}f(d)=>f(n)=\sum_{n|d}\mu(\frac{d}{n})F(d)F(n)=n∣d∑​f(d)=>f(n)=n∣d∑​μ(nd​)F(d)

二、几个概念和定理

  • 可乘函数(亦称积性函数):算术函数fff,满足 只要gcd(m,n)=1gcd(m,n) =1gcd(m,n)=1,就有f(mn)=f(m)f(n)f(mn)=f(m)f(n)f(mn)=f(m)f(n)。

  • ∑d∣n\sum _{d|n}∑d∣n​: 代表对n的所有正因子求和

  • 莫比乌斯函数

易证:莫比乌斯函数是可乘函数



三、两种形式的莫比乌斯反演证明

第一种形式的证明

F(n)=∑d∣nf(d)=>f(n)=∑d∣nμ(d)F(nd)F(n)=\sum_{d|n}f(d)=>f(n)=\sum_{d|n}\mu(d)F(\frac{n}{d})F(n)=d∣n∑​f(d)=>f(n)=d∣n∑​μ(d)F(dn​)
我们由恒等变形得:
f(n)=∑d∣nμ(d)F(nd)=∑d∣nμ(d)∑k∣ndf(k)=∑k∣nf(k)∑d∣nkμ(d)f(n)=\sum_{d|n}\mu(d)F(\frac{n}{d})=\sum_{d|n}\mu(d)\sum_{k|\frac{n}{d}}f(k)=\sum_{k|n}f(k)\sum_{d|\frac{n}{k}}\mu(d)f(n)=d∣n∑​μ(d)F(dn​)=d∣n∑​μ(d)k∣dn​∑​f(k)=k∣n∑​f(k)d∣kn​∑​μ(d)

∑d∣nμ(d)={1n==10n>1\sum_{d|n}\mu(d)=\begin{cases}1&n==1\\0&n>1\end{cases}d∣n∑​μ(d)={10​n==1n>1​
所以当且仅当nk=1\frac{n}{k}=1kn​=1,即n=kn=kn=k时,∑d∣nkμ(d)=1\sum_{d|\frac{n}{k}}\mu(d)=1∑d∣kn​​μ(d)=1,其余时候等于000。

∑k∣nf(k)∑d∣nkμ(d)=f(n)\sum_{k|n}f(k)\sum_{d|\frac{n}{k}}\mu(d)=f(n)k∣n∑​f(k)d∣kn​∑​μ(d)=f(n)
证毕。

第二种形式的证明

F(n)=∑n∣df(d)=>f(n)=∑n∣dμ(dn)F(d)F(n)=\sum_{n|d}f(d)=>f(n)=\sum_{n|d}\mu(\frac{d}{n})F(d)F(n)=n∣d∑​f(d)=>f(n)=n∣d∑​μ(nd​)F(d)

令k=dnk=\frac{d}{n}k=nd​,那么,就得到

f(n)=∑k=1+∞μ(k)F(nk)=∑k=1+∞μ(k)∑nk∣tf(t)=∑n∣tf(t)∑k∣tnμ(k)f(n)=\sum^{+\infty}_{k=1}\mu(k)F(nk)=\sum^{+\infty}_{k=1}\mu(k)\sum_{nk|t}f(t)=\sum_{n|t}f(t)\sum_{k|\frac{t}{n}}\mu(k)f(n)=k=1∑+∞​μ(k)F(nk)=k=1∑+∞​μ(k)nk∣t∑​f(t)=n∣t∑​f(t)k∣nt​∑​μ(k)

所以当且仅当tn=1\frac{t}{n}=1nt​=1,即t=nt=nt=n时, ∑k∣tnμ(k)=1\sum_{k|\frac{t}{n}}\mu(k)=1∑k∣nt​​μ(k)=1,其余时候等于000。
故得到

∑n∣tf(t)∑k∣tnμ(k)=f(n)\sum_{n|t}f(t)\sum_{k|\frac{t}{n}}\mu(k)=f(n)n∣t∑​f(t)k∣nt​∑​μ(k)=f(n)

证毕。

四、POJ 3904 Sky Code(入门例题)

Stancu likes space travels but he is a poor software developer and will never be able to buy his own spacecraft. That is why he is preparing to steal the spacecraft of Petru. There is only one problem – Petru has locked the spacecraft with a sophisticated cryptosystem based on the ID numbers of the stars from the Milky Way Galaxy. For breaking the system Stancu has to check each subset of four stars such that the only common divisor of their numbers is 1. Nasty, isn’t it? Fortunately, Stancu has succeeded to limit the number of the interesting stars to N but, any way, the possible subsets of four stars can be too many. Help him to find their number and to decide if there is a chance to break the system.

莫比乌斯反演模板,我们首先就要找到合适的 FFF 和fff。实际上,F和f的关系在于整除。我们可以假设

  • F(n)\tt F(n)F(n)为有多少个四元组满足 gcd(a,b,c,d)=n\tt gcd(a,b,c,d)=ngcd(a,b,c,d)=n 的整数倍

  • f(n)\tt f(n)f(n)为有多少个四元组满足 gcd(a,b,c,d)=n\tt gcd(a,b,c,d)=ngcd(a,b,c,d)=n

所以我们的目标就是求f(1)\tt f(1)f(1), 而实际上可以看出F与f构成了一组莫比乌斯变换对。有了反演公式,我们可以通过求F来求f,而这里面F很好求,要求F(n)我们只要在原数组中数出到能被n整除的数的个数m, 则C(m,4)\tt C(m,4)C(m,4)就是F(n)\tt F(n)F(n)

  • num[i]num[i]num[i] 表示在输入的 nnn 个数中有多少个是 iii 的倍数。
  • F(i)表示的是在输入的 nnn 个数中所有是i的倍数的这些数里挑选 444 个数的方案数。
  • F(i)=C(num[i],4)F(i) = C(num[i], 4)F(i)=C(num[i],4)。
  • f(n)=Σn∣dμ(d/n)F(d)f(n) = Σ_{n|d} μ(d/n)F(d)f(n)=Σn∣d​μ(d/n)F(d) 其中 n=1n = 1n=1。
  • 因为n=1,n∣dn = 1,n|dn=1,n∣d,所以d是所有范围(N)内的所有数。
  • ∴f(n)=μ(1)∗F(1)+μ(2)∗F(2)+⋅⋅⋅μ(N)∗F(N)∴ f(n) = μ(1) * F(1) + μ(2) * F(2) + ···μ(N) * F(N)∴f(n)=μ(1)∗F(1)+μ(2)∗F(2)+⋅⋅⋅μ(N)∗F(N)。

直接计算即可。

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstring>using namespace std;
typedef long long ll;
const int N = 20007, M = 50007, INF = 0x3f3f3f3f;
const double eps = 1e-6;int n, m;int mu[N], vis[N];
int prime[N], cnt;
int num[N];
int a[N];
//mu(x) -> 1/-1/0
//if(x分解质因数之后所有次数为1)mu[x] = 1;
//else mu[x] = 0;
void get_mu(int n)//得到莫比乌斯函数
{memset(vis, 0,sizeof vis);memset(mu, 0, sizeof mu);cnt = 0, mu[1] = 1;for(int i = 2; i <= n;++ i){if(!vis[i]){prime[cnt ++ ] = i;mu[i] = -1;//质数一定是-1}for(int j = 0; j < cnt && prime[j] * i <= n; ++ j){vis[prime[j] * i] = 1;if(i % prime[j] == 0)break;mu[i * prime[j]] = -mu[i];}}
}//num[i]表示在输入的n个数中有多少个是i的倍数
//F(i)表示的是在输入的n个数中所有是i的倍数的这些数里挑选4个数的方案数
//F(i) = C(num[i], 4)
//f(n) = Σ_{n|d} μ(d/n)F(d) 其中 n = 1
//因为n = 1,n|d,所以d是所有范围(N)内的所有数
//∴ f(n) = μ(1) * F(1) + μ(2) * F(2) + ···μ(N) * F(N)
void get_num()
{memset(num, 0, sizeof num);for(int i = 0; i < n; ++ i){int x = a[i];int m = sqrt(x);for(int j = 1; j <= m; ++ j){if(x % j == 0)//两个约数 ++ 表示这两个数多了一个倍数num[j] ++ , num[x / j] ++ ;}if(m * m == x)num[m] -- ;//防止完全平方数多+1}
}ll Cn4(int m)
{if(m == 0)return 0;return 1ll * m * (m - 1) * (m - 2) * (m - 3) / 24;
}int main()
{get_mu(N);while(scanf("%d", &n) != EOF){for(int i = 0; i < n; ++ i)scanf("%d", &a[i]);get_num();ll ans = 0;for(int i = 1 ; i < N; ++ i)ans += 1ll * mu[i] * Cn4(num[i]);printf("%lld\n", ans);}return 0;
}



【算法笔记】莫比乌斯反演(包含定理,两种形式的证明及入门经典模板)相关推荐

  1. 数学--数论--HDU 4675 GCD of Sequence(莫比乌斯反演+卢卡斯定理求组合数+乘法逆元+快速幂取模)

    先放知识点: 莫比乌斯反演 卢卡斯定理求组合数 乘法逆元 快速幂取模 GCD of Sequence Alice is playing a game with Bob. Alice shows N i ...

  2. MyBatis collection的两种形式——MyBatis学习笔记之九

    与association一样,collection元素也有两种形式,现介绍如下: 一.嵌套的resultMap 实际上以前的示例使用的就是这种方法,今天介绍它的另一种写法.还是以教师映射为例,修改映射 ...

  3. Java学习笔记:创建线程的两种方法

    Java学习笔记:创建线程的两种方法 一.预备工作 1.创建Maven项目ThreadDemo 2.在pom.xml里添加依赖 二.继承Thread类创建子线程

  4. SQL 关于apply的两种形式cross apply 和 outer apply

    SQL 关于apply的两种形式cross apply 和 outer apply 阅读目录 SQL 关于apply的两种形式cross apply 和 outer apply Sql学习第四天--S ...

  5. include的两种形式、CPP的搜索路径

    文章目录 1 include的两种形式.CPP的搜索路径 1 include的两种形式.CPP的搜索路径 #include "stdio.h" //1.源文件所在路径//2.-I选 ...

  6. Python基础day05【函数(函数传参的两种形式、函数形参)、拆包、引用、可变与不可变类型、引用做函数参数注意点】

    视频.源码.课件.软件.笔记:超全面Python基础入门教程[十天课程]博客笔记汇总表[黑马程序员]    目录 0.复习 1.函数传参的两种形式[掌握] 2.函数形参 2.1.缺省参数(默认参数) ...

  7. SQL 关于apply的两种形式cross apply 和 outer apply(转)

    转载链接:http://www.cnblogs.com/shuangnet/archive/2013/04/02/2995798.html apply有两种形式: cross apply 和 oute ...

  8. 【转载】SQL 关于apply的两种形式cross apply 和 outer apply

    apply有两种形式: cross apply 和 outer apply 先看看语法: <left_table_expression>  {cross|outer} apply < ...

  9. 在sql中case子句的两种形式

    case子句,在select后面可以进行逻辑判断. 两种形式:判断相等.判断不等 一.判断相等的语法: case 列名 when ...  then ... when ...  then ... el ...

最新文章

  1. Linux-DNS服务器的配置与管理(上)
  2. linux查看动态库导出的符号,Linux下控制动态库导出
  3. Acwing第 13 场周赛【未完结】
  4. 信息系统项目管理师优秀论文:项目采购管理
  5. 三维数组设置索引_10-Unity入门学习之C#基础9「数组」
  6. 一段简单的模拟服务器的代码(Selector)
  7. system流怎么判断为空_并行流ParallelStream中隐藏的陷阱
  8. SAP License:SAP记账码
  9. php公众号推荐,良心推荐6个优质实用又有趣的微信公众号!
  10. 游戏和数学笔记—常拿起来看看
  11. Java 匹配域名正则表达式
  12. 利用java网络通信技术实现一个迷你QQ
  13. 趣商宝微信招生方案 ,线上招生难,十大绝招帮您搞定微信吸粉!
  14. Spring学习-初识Spring
  15. f4menu2----Total Commander 增强型F4插件
  16. 使用阿里云IoT实现远程windows远程桌面
  17. 数据采集爬虫ip代理基本原理
  18. rospy基础--001_talker_listener
  19. 【Qt】QT鼠标和键盘事件
  20. 亏麻了,华为离职后年终奖照旧发。。

热门文章

  1. 用Python构建个性化智能闹钟
  2. 基于OpenCV实战:提取中心线
  3. 【OpenCV 4开发详解】图像LUT查找表
  4. 开源一个天气APP Build with React Native
  5. JavaEE框架整合之基于注解的SSH整合
  6. Oracle SQL Developer 的一个Bug
  7. 《ANSYS 14.0超级学习手册》一第2章 高级应用的基石——APDL
  8. 记一次数据中心云平台系统项目实施
  9. RocketMQ命令整理
  10. github心得体会