关于Mobius反演
数论函数
定义域为整数,值域为复数的函数
积性函数:若 \(\gcd(a,b)=1\) ,则\(f(ab)=f(a)+f(b)\)
感觉正确的结论
若有数论函数
\]
且\(g,k\)均为积性函数,则\(f\)为积性函数。
证明:
显然,有无\(k\)不干扰\(f\)是否积性,所以把\(f(n)\)简化为\(f(n)=\sum_{d|n}g(n)\)。
对于\(g\)函数:设\(x,y\)使得\(\gcd(x,y)=1\)
且 \(x=\prod_{i=1}^{s_x} {px_i}^{\alpha x_i},y=\prod_{i=1}^{s_y} {py_i}^{\alpha y_i}\).
则有\(\forall i,j\ px_i\ne py_j\)
\]
草率地得证。
除数函数
\(\sigma_x(n)=\sum_{d|n}d^x\)
除数函数为积性函数。
欧拉函数 \(\varphi\)
\(\varphi(n)=\)表示不超过 \(n\) 且与 \(n\) 互质的正整数的个数
\]
其中 \(n = {p_1}^{\alpha1} \cdot {p_2}^{\alpha2} \cdots {p_s}^{\alpha s} \cdot\) 是 \(n\) 的标准分解。
由此易见 \(\text{Euler}\) 函数是积性函数。
同时满足\(n=\sum_{d|n}\varphi(d)\)
线性求 \(\text{Euler}\) 函数:
#define int long long
int phi[3000005];
int n=3000000;
bool mark[3000005];
int prime[1000005];
int tot;
void getphi()
{
phi[1]=1;
for(int i=2;i<=n;i++)
{
if(mark[i]==false)
{
prime[++tot]=i;
phi[i]=i-1;
}
for(int j=1;j<=tot;j++)
{
if(i*prime[j]>n)
{
break;
}
mark[i*prime[j]]=true;
if(i%prime[j]==0)
{
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
phi[i*prime[j]]=phi[i]*phi[prime[j]];
}
}
for(int i=1;i<=n;i++)
{
phi[i]+=phi[i-1];
}
}
\(\text{Mobius}\)函数 \(\mu(n)\)
\]
证明:
\]
其中 \(\displaystyle\varepsilon(n)=\sum_{d\mid n}\mu(d)\) 即 \(\varepsilon=\mu*1\)
设 \(\displaystyle n=\prod_{i=1}^k{p_i}^{c_i},n'=\prod_{i=1}^k p_i\)
那么 \(\displaystyle\sum_{d\mid n}\mu(d)=\sum_{d\mid n'}\mu(d)=\sum_{i=0}^k C_k^i\cdot(-1)^k\)
根据二项式定理,易知该式子的值在 \(k=0\) 即 \(n=1\) 时值为 \(1\) 否则为 \(0\) ,这也同时证明了 \(\displaystyle\sum_{d\mid n}\mu(d)=[n=1]\)
#define int long long
int mu[3000005];
int n=3000000;
bool mark[3000005];
int prime[1000005];
int tot;
void getmu()
{
mu[1]=1;
for(int i=2;i<=n;i++)
{
if(mark[i]==false)
{
prime[++tot]=i;
mu[i]=-1;
}
for(int j=1;j<=tot;j++)
{
if(i*prime[j]>n)
{
break;
}
mark[i*prime[j]]=true;
if(i%prime[j]==0)
{
mu[i*prime[j]]=0;
break;
}
mu[i*prime[j]]=-mu[i];
}
}
}
\(\text{Dirichlet}\)卷积
\(\text{ID}:\text{ID(i)=i}\)
\(\text{1}:\text{1(i)=1}\)
定义两个数论函数的\(\text{Dirichlet}\)卷积为:
\]
性质:\(\text{Dirichlet}\)卷积满足交换律和结合律。
单位元:\(\varepsilon\),\(\varepsilon(n)=[n==1]\),任何函数卷\(\varepsilon\)都为其本身.
\(1*\mu=\varepsilon\)
\(\mu * \text{ID} = \varphi\)
\(1*\text{ID}=\sigma\)
莫比乌斯反演
公式:设 \(f(n),g(n)\) 为两个数论函数。
如果有
\]
那么有
\]
证明:
原命题等价于:已知 \(f=g*1\) ,证明 \(g=f*\mu\)
显然: \(f*\mu=g*1*\mu= g*\varepsilon=g\) (其中 \(1*\mu=\varepsilon\) )
同时,还有另一种\(\text{Mobius}\)反演:
如果有
\]
那么有
\]
整除分块
当遇到形如
\]
的柿子时。
可以采用\(O(\sqrt {n})\)复杂度的算法:整除分块
易证:对于部分连续的\(i\),\(\frac{n}{i}\)的值是相同的,考虑把它们合并计算,可以发现发现对于每一个值相同的块,它的最后一个数是n/(n/i)
。
简略证明:\(\frac{n}{i}\)就是所求的值,设为\(x\),那么可证对于值\(x\),它所在的块的最后一个数是\(\frac{n}{x}\)。
- 证明:反证法:对于数\(\frac{n}{x}+1\),它所在的块的值为\(\frac{n}{\frac{n}{x}+1}\),且\(\frac{n}{\frac{n}{x}+1}-x=\frac{x^2}{n+x}>0\)。$\therefore \(数\)\frac{n}{x}+1 \(和数\)\frac{n}{x}$不在同一个块中。
然后,原命题得证。
所以,易得计算原式方法。
for(int l=1,r;l<=n;l=r+1)
{
r=n/(n/l);
ans+=(r-l+1)*(n/l);
}
P2257 YY的GCD
设\(f(d)=\sum_{i=1}^{n}\sum_{i=1}^{m}[gcd(i,j)=d]\),
\(F(n)=\sum_{n\mid d}f(d)=\lfloor \frac{N}{n} \rfloor \times \lfloor \frac{M}{n} \rfloor\)
由莫比乌斯反演:\(f(n)=\sum_{n|d}\mu(\frac{d}{n})F(d)\)
\(Ans=\sum_{i=1}^{n}\sum_{i=1}^{m}[gcd(i,j)=prim]\)
\(=\sum_{p\in prim}\sum_{i=1}^{n}\sum_{i=1}^{m}[gcd(i,j)=p]\)
\(=\sum_{p\in prim}f(p)\)
\(=\sum_{p\in prim}\sum_{p|d}\mu(\frac{d}{p})F(d)\)
改为枚举\(\frac{d}{p}\):
\(Ans=\sum_{p\in prim}\sum_{d}^{min(\lfloor \frac{n}{p} \rfloor,\lfloor \frac{m}{p} \rfloor)}\mu(d)F(dp)\)
\(=\sum_{p\in prim}\sum_{d}^{min(\lfloor \frac{n}{p} \rfloor,\lfloor \frac{m}{p} \rfloor)}\mu(d) \times \lfloor \frac{N}{dp} \rfloor \times \lfloor \frac{M}{dp} \rfloor\)
设\(dp=T,t=p\)
\(Ans=\sum_{t\in prim}\sum_{d}^{min(\lfloor \frac{n}{t} \rfloor,\lfloor \frac{m}{t} \rfloor)}\mu(\frac{T}{t}) \times \lfloor \frac{N}{T} \rfloor \times \lfloor \frac{M}{T} \rfloor\)
\(=\sum_{T=1}^{min(n,m)}\sum_{t\in prim,t|T}\mu(\frac{T}{t}) \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_{t\in prim,t|T}\mu(\frac{T}{t})\)
代码:
//sum即为\(\sum_{t\in prim,t|T}\mu(\frac{T}{t})\)的前缀和
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int prime[10000005];
int mu[10000005];
ll f[10000005];
ll sum[10000005];
bool vis[10000005];
int cnt;
void init()
{
mu[1]=1;
for(int i=2;i<=10000000;i++)
{
if(vis[i]==false)
{
mu[i]=-1;
prime[++cnt]=i;
}
for(int j=1;j<=cnt&&i*prime[j]<=10000000;j++)
{
vis[i*prime[j]]=true;
if(i%prime[j]==0)
{
break;
}
mu[i*prime[j]]=-mu[i];
}
}
for(int i=1;i<=cnt;i++)
{
for(int j=1;j*prime[i]<=10000000;j++)
{
f[j*prime[i]]+=mu[j];
}
}
for(int i=1;i<=10000000;i++)
{
sum[i]=sum[i-1]+f[i];
}
}
ll solve(int a,int b)//运用整除分块
{
ll ans=0;
if(a>b)
{
swap(a,b);
}
for(int l=1,r=0;l<=a;l=r+1)
{
r=min(a/(a/l),b/(b/l));
ans+=(ll)(sum[r]-sum[l-1])*(a/l)*(b/l);
}
return ans;
}
signed main()
{
init();
int T;
cin>>T;
for(int i=1;i<=T;i++)
{
int a,b;
scanf("%d %d",&a,&b);
printf("%lld\n",solve(a,b));
}
return 0;
}
常用柿子
\]
\]
调和数
\(H_n=\sum_{k=1}^{n}\frac{1}{k}\)
\(H_n=\ln n\ + \gamma\ + o(1)\)
\(\sum_{d=1}^n \lfloor\frac{n}{d}\rfloor = \text{O}(n \log n)\)
杜教筛
快速求出\(\phi(n)=\sum_{i=1}^n \varphi(i)\)
由于\(\text{ID}=\varphi * 1\)
可得\(\frac{n(n+1)}{2}=\sum_{k=1}^n\sum_{d|k}\varphi(\frac{k}{d})\)
\(=\sum_{k=1}^n\sum_{d=1}^{\lfloor \frac{n}{k} \rfloor}\varphi(d)\)
\(\therefore \phi(n)=\frac{n(n+1)}{2}-\sum_{d=2}^n \phi(\lfloor \frac{n}{d} \rfloor)\)
右边为子问题,可以递归解决,再加整除分块,可以保证每个点被计算一遍
复杂度\(O(n^{\frac{3}{4}})\)
代码:
#include<bits/stdc++.h>
using namespace std;
#define re register
#define ll long long
#define N 5500000
ll phi[N+5];
int mu[N+5];
int prim[N+5];
bool mark[N+5];
int cnt;
unordered_map<int,ll> aphi;
unordered_map<int,int> amu;
void init()
{
phi[1]=1;
mu[1]=1;
for(re int i=2;i<=N;i++)
{
if(mark[i]==false)
{
phi[i]=i-1;
mu[i]=-1;
prim[++cnt]=i;
}
for(re int j=1;j<=cnt;j++)
{
if(i*prim[j]>N)
{
break;
}
mark[i*prim[j]]=true;
if(i%prim[j]==0)
{
phi[i*prim[j]]=phi[i]*prim[j];
mu[i*prim[j]]=0;
break;
}
phi[i*prim[j]]=phi[i]*phi[prim[j]];
mu[i*prim[j]]=-mu[i];
}
}
for(re int i=1;i<=N;i++)
{
phi[i]+=phi[i-1];
mu[i]+=mu[i-1];
}
}
ll getphi(int x)
{
if(x<=N)
{
return phi[x];
}
if(aphi[x]!=0)
{
return aphi[x];
}
ll ans=(ll)x*(x+1)/2;
for(int l=2,r=0;r!=2147483647&&l<=x;l=r+1)
{
r=x/(x/l);
ans-=(ll)(r-l+1)*getphi(x/l);
}
return aphi[x]=ans;
}
int getmu(int x)
{
if(x<=N)
{
return mu[x];
}
if(amu[x]!=0)
{
return amu[x];
}
int ans=1;
for(int l=2,r=0;r!=2147483647&&l<=x;l=r+1)
{
r=x/(x/l);
ans-=(r-l+1)*getmu(x/l);
}
return amu[x]=ans;
}
int main()
{
init();
int T;
cin>>T;
int x;
for(int i=1;i<=T;i++)
{
scanf("%d",&x);
printf("%lld %d\n",getphi(x),getmu(x));
}
return 0;
}
关于Mobius反演的更多相关文章
- SPOJ PGCD (mobius反演 + 分块)
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove 题意 :求满足gcd(i , j)是素数(1 &l ...
- mobius反演讲解
mobius反演的基本形式为,假设知道函数F(x)=Σf(d) d|x,那么我们可以推出f(x)=Σmiu(d)*F(x/d) d|x,另一基本形式为假设知道函数F(x)=Σf(d) x|d,那么我们 ...
- [基本操作] Mobius 反演, Dirichlet 卷积和杜教筛
Dirichlet 卷积是两个定义域在正整数上的函数的如下运算,符号为 $*$ $(f * g)(n) = \sum_{d|n}f(d)g(\frac{n}{d})$ 如果不强调 $n$ 可简写为 $ ...
- Mobius反演与积性函数前缀和演学习笔记 BZOJ 4176 Lucas的数论 SDOI 2015 约数个数和
下文中所有讨论都在数论函数范围内开展. 数论函数指的是定义域为正整数域, 且值域为复数域的函数. 数论意义下的和式处理技巧 因子 \[ \sum_{d | n} a_d = \sum_{d | n} ...
- Mobius 反演与杜教筛
积性函数 积性函数 指对于所有互质的整数 aaa 和 bbb 有性质 f(ab)=f(a)f(b)f(ab)=f(a)f(b)f(ab)=f(a)f(b) 的数论函数. 特别地,若所有的整数 aaa ...
- Mobius反演学习
这篇文章参考了许多资料和自己的理解. 先放理论基础. 最大公约数:小学学过,这里只提一些重要的公式: $·$若$a=b$,则$\gcd(a,b)=a=b$: $·$若$\gcd(a,b)=d$,则$\ ...
- Note -「Mobius 反演」光速入门
目录 Preface 数论函数 积性函数 Dirichlet 卷积 Dirichlet 卷积中的特殊函数 Mobius 函数 & Mobius 反演 Mobius 函数 Mobius 反演 基 ...
- 【莫比乌斯反演】关于Mobius反演与gcd的一些关系与问题简化(bzoj 2301 Problem b&&bzoj 2820 YY的GCD&&BZOJ 3529 数表)
首先我们来看一道题 BZOJ 2301 Problem b Description 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd( ...
- (暂时弃坑)(半成品)ACM数论之旅18---反演定理 第二回 Mobius反演(莫比乌斯反演)((づ ̄3 ̄)づ天才第一步,雀。。。。)
莫比乌斯反演也是反演定理的一种 既然我们已经学了二项式反演定理 那莫比乌斯反演定理与二项式反演定理一样,不求甚解,只求会用 莫比乌斯反演长下面这个样子(=・ω・=) d|n,表示n能够整除d,也就是d ...
随机推荐
- AngularJS-自定义过滤器 ng-repeat 求和
<!DOCTYPE html> <html lang="zh_CN"> <head> <meta charset="UTF-8& ...
- 利用JS提交表单的几种方法和验证(必看篇)
第一种方式:表单提交,在form标签中增加onsubmit事件来判断表单提交是否成功 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <scr ...
- Linux防火墙命令
linux 查看防火墙状态 1.查看防火墙状态 systemctl status firewalld firewall-cmd --state #查看默认防火墙状态(关闭后显示notrunning ...
- C# ObjectArx cad二次开发
1 环境搭建:安装CAD 和objectArx库,这里安装的是cad2012和objectArx2010 ,vs是2010 2 新建一个类库项目,引用objectArx安装目录下inc文件夹下的AcD ...
- String变量的两种创建方式
在java中,有两种创建String类型变量的方式: String str01="abc";//第一种方式 String str02=new String("abc&qu ...
- BIEE入门(二)物理层的定义
使用BIEE的第一步是使用admintool去建立一个多维数据模型,而建立多维数据模型的第一步则是建立物理层,请注意因为BIEE本身并不存 储数据,所以所谓BIEE物理层的意义是需要在BIEE里建立各 ...
- Dynamics CRM RibbonWorkbench工具使用
这边用的是RibbonWorkbench2016的工具,导入RibbonWorkbench2016解决方案即可.导入成功后在解决方案下面会多出一个快捷键小图标. 一.基本介绍 二.列表页获取选中记录的 ...
- Linux下实现免密码登录
1.Linux下生成密钥 ssh-keygen的命令手册,通过”man ssh-keygen“命令: 通过命令”ssh-keygen -t rsa“ 生成之后会在用户的根目录生成一个 “.ssh”的文 ...
- PHP:使用php,循环html中的select标签与Php数据
select标签,我们都知道是下拉列表,这里,我们使用foreach循环,将select中的数据进行输出 例子: 1.数据表:mimi_article,表中有个字段,为1或0,表示着是或否 2.通过p ...
- Scrum第一次冲刺
1.项目描述 为了长大学子的便捷,避免遭遇官网爆炸而无法查询成绩,课表等相关个人信息.我们决定开发长大Tips(分担官网的压力). 2.基本业务 用户可以通过学号加密码登入长大Tips 用户可以在在用 ...