莫比乌斯反演学习笔记
1. 整除分块
1.1. 简述
例题:求
这个东西就是指将
性质1:分块的个数
证明:当
当
性质2:
证明:
则有
所以
所以,在求解如上例题时,不必算出所有的值,只要知道左右端点即可
1.2. 例题
1.2.1. 约数和
板子,求出左右端点然后等差数列求和即可
点击查看代码
#include<cstdio>
#define ll long long
using namespace std;
ll get(ll x)
{
ll res=0;
for(ll i=1;i<=x;i++)
{
ll c=x/i,j,sum;
j=x/c;
sum=(i+j)*(j-i+1)/2;
res+=sum*c;
i=j;
}
return res;
}
int main()
{
ll x,y;
scanf("%lld%lld",&x,&y);
printf("%lld",get(y)-get(x-1));
return 0;
}
1.2.2. [CQOI2007] 余数求和
可以把余数转化为
点击查看代码
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
ll n,k,ans;
int main()
{
scanf("%lld%lld",&n,&k);
for(ll i=1;i<=min(n,k);i++)
{
ll c=k/i,j,sum;
j=k/c;
j=min(j,n);
sum=(i+j)*(j-i+1)/2;
ans+=sum*c;
i=j;
}
printf("%lld",n*k-ans);
return 0;
}
2. 狄利克雷卷积
数列
乘法运算:
积性函数:
欧拉函数和莫比乌斯函数都是积性函数
2.1. 欧拉函数
定义:
性质:
证明:
观察以 12 为分母的真分数:
化简并按分母分组得:
发现分母都是 12 的约数,个数为
推广到
2.2. 莫比乌斯函数
定义:
性质:
证明:
当
当
记
- 莫比乌斯函数和欧拉函数的关系:
证明:
记
2.3. 狄利克雷卷积
定义
规律:满足交换律,结合律,分配律
常用函数:
- 元函数:
- 常数函数:
- 恒等函数:
常用卷积关系:
3. 和式的变换
变换规则:1.结合律 2.交换律 3.分配律
变换技术:
- 替换条件式:
- 替换指标变量:
- 交换求和次序:
- 分离变量:
相关练习
YY的GCD
https://www.gxyzoj.com/d/gxyznoi/p/P5
显然的,原题可以转化为:
但是这样无法计算,记
预处理一下莫比乌斯函数即可
点击查看代码
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const int N=1e7;
int T,n,m,vis[N+5],p[N+5],mu[N+5],cnt,f[N+5];
void init()
{
mu[1]=1;
for(int i=2;i<=N;i++)
{
if(!vis[i])
{
p[++cnt]=i;
mu[i]=-1;
}
for(int j=1;i*p[j]<=N;j++)
{
vis[i*p[j]]=1;
if(i%p[j]==0) break;
mu[i*p[j]]=-mu[i];
}
}
for(int i=1;i<=cnt;i++)
{
for(int j=p[i];j<=N;j+=p[i])
{
f[j]+=mu[j/p[i]];
}
}
for(int i=1;i<=N;i++)
{
f[i]+=f[i-1];
}
}
ll clac(int n,int m)
{
ll ans=0;
if(n>m) swap(n,m);
for(int i=1;i<=n;i++)
{
int j=min(n/(n/i),m/(m/i));
ans+=1ll*(f[j]-f[i-1])*(n/i)*(m/i);
i=j;
}
return ans;
}
int main()
{
init();
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
printf("%lld\n",clac(n,m));
}
return 0;
}
[SDOI2015] 约数个数和
有一个公式
经过推式子和化简为求
做两次整除分块即可
点击查看代码
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const int N=5e4;
int T,n,m,vis[N+5],p[N+5],mu[N+5],sum[N+5],cnt;
ll f[N+5];
void init()
{
mu[1]=1;
for(int i=2;i<=N;i++)
{
if(!vis[i])
{
p[++cnt]=i;
mu[i]=-1;
}
for(int j=1;i*p[j]<=N;j++)
{
vis[i*p[j]]=1;
if(i%p[j]==0) break;
mu[i*p[j]]=-mu[i];
}
}
for(int i=1;i<=N;i++)
{
sum[i]=sum[i-1]+mu[i];
for(int l=1;l<=i;l++)
{
int r=i/(i/l);
f[i]+=1ll*(r-l+1)*(i/l);
l=r;
}
}
}
ll clac(int n,int m)
{
if(n>m) swap(n,m);
ll ans=0;
for(int i=1;i<=n;i++)
{
int j=min(n/(n/i),m/(m/i));
ans+=(sum[j]-sum[i-1])*f[n/i]*f[m/i];
i=j;
}
return ans;
}
int main()
{
scanf("%d",&T);
init();
while(T--)
{
scanf("%d%d",&n,&m);
printf("%lld\n",clac(n,m));
}
return 0;
}
3. 莫比乌斯反演
若
则
证明:条件等价于
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律