【数论】卷积反演大集合
不知道为啥脑抽要学数论,骂声一片中发现数论还没入门(悲)。
1. 狄利克雷卷积与数论函数#
1.1 数论函数#
定义:数论函数为值域为整数的函数。
简单数论函数:
,恒等函数,恒等为 。 ,元函数,卷积中的单位元,若 , 。否则为 。 ,单位函数, 。 ,幂函数, 。
在数论函数的基础上,有以下。
定义:完全积性函数,
定义:积性函数,
欧拉函数与莫比乌斯函数皆为积性函数。证明显然。
1.2 狄利克雷卷积#
定义:
或
交换律:
结合律:
会用就行。
2. 莫比乌斯反演#
2.1 莫比乌斯函数#
函数
由狄利克雷卷积得:
于是乎就有:
若已知
变形:
这里的
积性函数的逆还是积性函数,所以
2.2 莫比乌斯反演#
- 嵌套式反演公式:由
得 。
好了,你现在已经数论入门了!!。
3. 欧拉反演#
3.1 欧拉函数#
记
计算方法:将总数减去与
因数分解可得:
计算欧拉函数的步骤中运用到了容斥原理,可见容斥原理的应用范围非常广。
欧拉函数的性质:
-
若
,则有 ,即欧拉函数为积性函数。证明:
设
为 的质因子集合,集合元素记为 , 为 的质因子集合,集合元素记为 。 , . -
若
为质数, .证明:
为质数, 小于 的正整数中与 互质的数的个数为 . -
若
为质数, .证明:
为质数, 与 不互质的数只能为 的倍数,共有 个。 .
不用怀疑了,全从数学大礼包上贺的。
3.2 欧拉反演#
- 嵌套式欧拉反演:由
得
4. 反演习题#
P3455 [POI2007] ZAP-Queries#
Problem#
给定
Solve#
莫反好题。
转化形式:
代入嵌入式莫比乌斯反演:
由
交换枚举顺序:
化简:
Code#
点击查看代码
#include <bits/stdc++.h>
#define int long long
#define H 19260817
#define rint register int
#define For(i,l,r) for(rint i=l;i<=r;++i)
#define FOR(i,r,l) for(rint i=r;i>=l;--i)
#define MOD 1000003
#define mod 1000000007
using namespace std;
inline int read() {
rint x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
void print(int x){
if(x<0){putchar('-');x=-x;}
if(x>9){print(x/10);putchar(x%10+'0');}
else putchar(x+'0');
return;
}
const int N = 5e4 + 10;
int T, a, b, d, prime[N], tot, mu[N], sum[N];
bool vis[N];
void Euler() {
vis[1] = mu[1] = 1;
for (int i = 2; i <= N-10; i++) {
if(!vis[i]) prime[++tot] = i, mu[i] = -1;
for (int j = 1; i * prime[j] <= N-10 && j <= tot; j++) {
vis[i * prime[j]] = 1;
mu[i * prime[j]] = (i % prime[j] == 0 ? 0 : -mu[i]);
if(i % prime[j] == 0) break;
}
}
}
signed main() {
T = read();
Euler();
For(i,1,N) {
sum[i] = sum[i-1] + mu[i];
}
while(T--) {
a = read(), b = read(), d = read();
int ans = 0, n = a / d, m = b / d;
for (int l = 1, r = 0; l <= min(n, m); l = r + 1) {
r = min(n / (n / l), m / (m / l));
ans += (sum[r] - sum[l-1]) * (n / l) * (m / l);
}
cout << ans << '\n';
}
return 0;
}
P2522 [HAOI2011] Problem b#
Problem#
给定
Solve#
根据上一题得到启发:
若上题求得是一个
在上一题的基础上二维前缀和求解即可。
Code#
点击查看代码
#include <bits/stdc++.h>
#define int long long
#define H 19260817
#define rint register int
#define For(i,l,r) for(rint i=l;i<=r;++i)
#define FOR(i,r,l) for(rint i=r;i>=l;--i)
#define MOD 1000003
#define mod 1000000007
using namespace std;
inline int read() {
rint x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
void print(int x){
if(x<0){putchar('-');x=-x;}
if(x>9){print(x/10);putchar(x%10+'0');}
else putchar(x+'0');
return;
}
const int N = 5e4 + 10;
int T, a, b, c, d, k, prime[N], tot, mu[N], sum[N];
bool vis[N];
void Euler() {
vis[1] = mu[1] = 1;
for (int i = 2; i <= N-10; i++) {
if(!vis[i]) prime[++tot] = i, mu[i] = -1;
for (int j = 1; i * prime[j] <= N-10 && j <= tot; j++) {
vis[i * prime[j]] = 1;
mu[i * prime[j]] = (i % prime[j] == 0 ? 0 : -mu[i]);
if(i % prime[j] == 0) break;
}
}
}
int calc(int n, int m) {
int ans = 0;
n /= k, m /= k;
for (int l = 1, r = 0; l <= min(n, m); l = r + 1) {
r = min(n / (n / l), m / (m / l));
ans += (sum[r] - sum[l-1]) * (n / l) * (m / l);
}
return ans;
}
signed main() {
T = read();
Euler();
For(i,1,N) {
sum[i] = sum[i-1] + mu[i];
}
while(T--) {
a = read(), b = read(), c = read(), d = read(), k = read();
cout << calc(b, d) - calc(a-1, d) - calc(b, c-1) + calc(a-1, c-1) << '\n';
}
return 0;
}
P2158 [SDOI2008] 仪仗队#
Problem#
给定一个
Solve#
若
若存在点
所求即为
莫比乌斯反演求解。
注意细节:计算时按
Code#
点击查看代码
#include <bits/stdc++.h>
#define int long long
#define H 19260817
#define rint register int
#define For(i,l,r) for(rint i=l;i<=r;++i)
#define FOR(i,r,l) for(rint i=r;i>=l;--i)
#define MOD 1000003
#define mod 1000000007
using namespace std;
inline int read() {
rint x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
void print(int x){
if(x<0){putchar('-');x=-x;}
if(x>9){print(x/10);putchar(x%10+'0');}
else putchar(x+'0');
return;
}
const int N = 4e4 + 10;
int n, prime[N], tot, mu[N], sum[N];
bool vis[N];
void Eular() {
vis[1] = mu[1] = 1;
for (int i = 2; i <= 4e4; i++) {
if(!vis[i]) prime[++tot] = i, mu[i] = -1;
for (int j = 1; i * prime[j] <= 4e4 && j <= tot; j++) {
vis[i * prime[j]] = 1;
mu[i * prime[j]] = (i % prime[j] == 0 ? 0 : -mu[i]);
if(i % prime[j] == 0) break;
}
}
}
int calc(int n) {
int ans = 0; n--;
for (int l = 1, r; l <= n; l = r + 1) {
r = n / (n / l);
ans += (sum[r] - sum[l-1]) * (n / l) * (n / l);
}
return ans + 2;
}
signed main() {
n = read();
Eular();
For(i,1,n) sum[i] = sum[i-1] + mu[i];
cout << (n == 1 ? 0 : calc(n)) << '\n';
return 0;
}
P2398 GCD SUM#
Problem#
给定正整数
Solve#
欧拉反演模板题。
原式:
嵌入式欧拉反演:
由
转化形式:
化简:
前缀和 + 整除分块即可求解。注意欧拉筛欧拉函数时,是以质数为讨论根据。
Code#
点击查看代码
#include <bits/stdc++.h>
#define int long long
#define H 19260817
#define rint register int
#define For(i,l,r) for(rint i=l;i<=r;++i)
#define FOR(i,r,l) for(rint i=r;i>=l;--i)
#define MOD 1000003
#define mod 1000000007
using namespace std;
inline int read() {
rint x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
void print(int x){
if(x<0){putchar('-');x=-x;}
if(x>9){print(x/10);putchar(x%10+'0');}
else putchar(x+'0');
return;
}
const int N = 1e5 + 10;
int n, prime[N], tot, phi[N], sum[N];
bool vis[N];
void Eular() {
vis[1] = phi[1] = 1;
for (int i = 1; i <= N - 1; i++) {
if(!vis[i]) prime[++tot] = i, phi[i] = i-1;
for (int j = 1; j <= tot && i * prime[j] <= N - 1; j++) {
vis[i * prime[j]] = 1;
phi[i * prime[j]] = (i % prime[j] == 0 ? phi[i] * prime[j] : phi[i] * (prime[j]-1));
if(i % prime[j] == 0) break;
}
}
}
int calc(int n) {
int ans = 0;
for (int l = 1, r; l <= n; l = r + 1) {
r = n / (n / l);
ans += (sum[r] - sum[l-1]) * (n / l) * (n / l);
}
return ans;
}
signed main() {
n = read();
Eular();
For(i,1,n) sum[i] = sum[i-1] + phi[i];
cout << calc(n) << '\n';
return 0;
}
作者:Daniel-yao
出处:https://www.cnblogs.com/Daniel-yao/p/18026382
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】