狄利克雷卷积
符号即约定
- , 表示当 为真时取值为 , 为假时取值为
- , 常函数 ,恒为
- , 狄利克雷卷积单位元
- ,恒等函数
- , 幂函数
- , 约数个数函数
- , 约数和函数
- , 除数函数,表示 所有因数 次方的和。
- , 欧拉函数
- , 莫比乌斯函数
- 无特殊说明, 为质数
定义
狄利克雷卷积 和 是定义在数论函数间的一种二元运算,可以定义为:
性质
交换律
证明
结合律
证明
分配律
证明
性质
显然。
性质
证明
特殊狄利克雷卷积
狄利克雷逆元
定义
如果 且 ,则称 是 的狄利克雷逆元
求法
莫比乌斯函数
定义
性质
证明
设
那么有:
显然当且仅当 即 时值为 , 否则为
这也证明了
与欧拉函数的关系
显然莫比乌斯函数是积性函数,所以可以线性筛:
void Get_Mu(int N) {
Mu[1] = 1;
for(int i = 2; i <= N; i++) {
if(!Vis[i]) {
Mu[i] = -1;
Prime[++Cnt] = i;
}
for(int j = 1; j <= Cnt && i * Prime[j] <= N; j++) {
Vis[i * Prime[j]] = true;
if(i % Prime[j] == 0) break;
else Mu[i * Prime[j]] = -Mu[i];
}
}
}
莫比乌斯反演
公式
证明见上文性质。
例题选讲
[HAOI2011]Problem b
题意
求
思路
我们浅浅的容斥一下,分成 块,每一块都为:
替换下标得:
反演得:
更换枚举顺序得:
显然 中 得倍数有 个,故原式化为:
然后就可以数论分块了。
思路
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 50010;
inline void read(int &x)
{
x=0;
static int p;p=1;
static char c;c=getchar();
while(!isdigit(c)){if(c=='-')p=-1;c=getchar();}
while(isdigit(c)) {x=(x<<1)+(x<<3)+(c-48);c=getchar();}
x*=p;
}
bool Vis[MAXN];
int Prime[MAXN] , Mu[MAXN] , Sum[MAXN] , Cnt , K , T;
int a , b , c , d;
void Get_Mu(int N) {
Mu[1] = 1;
for(int i = 2; i <= N; i++) {
if(!Vis[i]) {
Mu[i] = -1;
Prime[++Cnt] = i;
}
for(int j = 1; j <= Cnt && i * Prime[j] <= N; j++) {
Vis[i * Prime[j]] = true;
if(i % Prime[j] == 0) break;
else Mu[i * Prime[j]] = -Mu[i];
}
}
for(int i = 1; i <= N; i++) Sum[i] = Sum[i - 1] + Mu[i];
}
long long Ans;
long long Solve (int a , int b) {
Ans = 0;
for(int l = 1 , r; l <= min(a , b); l = r + 1) {
r = min(a / (a / l) , b / (b / l));
Ans += (1ll * a / (1ll * l * K)) * (1ll * b / (1ll * l * K)) * (Sum[r] - Sum[l - 1]);
}
return Ans;
}
int main() {
Get_Mu(50000);
read(T);
while(T--) {
read(a);
read(b);
read(c);
read(d);
read(K);
printf("%lld\n" ,Solve(b , d) - Solve(b , c - 1) - Solve(a - 1 , d) + Solve(a - 1 , c - 1));
}
return 0;
}
YY的GCD
题意
求
思路
枚举质数得:
同时除以 得
反演得
同第一题,显然
设 ,得
枚举 得
代码
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e7 + 10;
int T , N , M;
bool Vis[MAXN];
int Prime[MAXN] , Mu[MAXN] , Sum[MAXN] , Cnt , F[MAXN];
void Get_Mu(int N) {
Mu[1] = 1;
for(int i = 2; i <= N; i++) {
if(!Vis[i]) {
Mu[i] = -1;
Prime[++Cnt] = i;
}
for(int j = 1; j <= Cnt && i * Prime[j] <= N; j++) {
Vis[i * Prime[j]] = true;
if(i % Prime[j] == 0) break;
else Mu[i * Prime[j]] = -Mu[i];
}
}
for(int i = 1; i <= Cnt; i++) {
for(int j = 1; Prime[i] * j <= N; j++) {
F[j * Prime[i]] += Mu[j];
}
}
for(int i = 1; i <= N; i++) Sum[i] = Sum[i - 1] + F[i];
}
long long AC(int a , int b) {
long long Ans = 0;
for(int l = 1 , r = 0; l <= a; l = r + 1) {
r = min(a / (a / l) , b / (b / l));
Ans += (long long)(Sum[r] - Sum[l - 1]) * (long long)(a / l) * (long long)(b / l);
}
return Ans;
}
int main() {
ios::sync_with_stdio(false);
Get_Mu(MAXN - 10);
cin >> T;
while(T--) {
cin >> N >> M;
cout << AC(min(N , M) , max(N , M)) << endl;
}
return 0;
}
[SDOI2015]约数个数和