莫比乌斯函数 μ ( n ) \mu(n) μ(n)
μ
(
n
)
=
{
1
n
=
1
(
−
1
)
k
n
=
p
1
p
2
.
.
.
p
k
0
e
l
s
e
\mu(n)=\left\{ \begin{array}{cl} 1 && {n = 1}\\ (-1)^k && {n = p_1p_2...p_k}\\ 0 && {else}\\ \end{array} \right.
μ(n)=⎩
⎨
⎧1(−1)k0n=1n=p1p2...pkelse
当
n
n
n有平方因子时,
μ
(
n
)
=
0
\mu(n) = 0
μ(n)=0.
当
n
n
n没有平方因子时,
μ
(
n
)
\mu(n)
μ(n)取决于分解的素数个数
性质
- 对任意正整数n, ∑ d ∣ n μ ( d ) = [ n = 1 ] \sum_{d|n} \mu(d) = [n = 1] ∑d∣nμ(d)=[n=1]
- 对任意正整数n, ∑ d ∣ n μ ( d ) d = ϕ ( n ) n \sum_{d|n} \frac{\mu(d)}{d} = \frac{\phi(n)}{n} ∑d∣ndμ(d)=nϕ(n)
莫比乌斯函数是积性函数,可以利用线性筛求出莫比乌斯函数
void get_mu(int n){
mu[1] = 1;
for(int i = 2; i <= n; i++){
if(!vis[i]){
prime[++cnt] = i;
mu[i] = -1;
}
for(int j = 1; j <= cnt&&i*prime[j] <= n; j++){
vis[i*prime[j]] = 1;
if(i%prime[j] == 0){
mu[i*prime[j]] = 0; //也可以直接break
break;
}
else
mu[i*prime[j]] = -mu[i];
}
}
}
莫比乌斯反演
F(n)与f(n)定义在非负整数集上,且满足:
F
(
n
)
=
∑
d
∣
n
f
(
d
)
F(n) = \sum\limits_{d|n}f(d)
F(n)=d∣n∑f(d)则:
f
(
n
)
=
∑
d
∣
n
μ
(
d
)
F
(
n
d
)
f(n) = \sum\limits_{d|n}\mu(d)F(\frac{n}{d})
f(n)=d∣n∑μ(d)F(dn)
F(n)与f(n)定义在非负整数集上,且满足:
F
(
n
)
=
∑
n
∣
d
f
(
d
)
F(n) = \sum\limits_{n|d}f(d)
F(n)=n∣d∑f(d)则:
f
(
n
)
=
∑
n
∣
d
μ
(
d
n
)
F
(
d
)
f(n) = \sum\limits_{n|d}\mu(\frac{d}{n})F(d)
f(n)=n∣d∑μ(nd)F(d)
YY的GCD
题意:
∑ i = 1 N ∑ j = 1 M [ g c d ( i , j ) = p r i m e ] \sum\limits_{i=1}\limits^{N}\sum\limits_{j=1}\limits^{M}[gcd(i,j) = prime] i=1∑Nj=1∑M[gcd(i,j)=prime]
数据组数 T = 1 0 4 N , M ≤ 1 0 7 T = 10^4\quad N, M \le 10^7 T=104N,M≤107
解析:
设 f ( d ) f(d) f(d)为 g c d ( i , j ) = d gcd(i,j) = d gcd(i,j)=d的个数,设 F ( n ) F(n) F(n)为 g c d ( i , j ) = k n ( k ≥ 1 ) gcd(i,j) = kn (k \ge 1) gcd(i,j)=kn(k≥1) 的个数 f ( d ) = ∑ i = 1 N ∑ j = 1 M [ g c d ( i , j ) = d ] f(d) = \sum\limits_{i=1}\limits^{N}\sum\limits_{j=1}\limits^{M}[gcd(i,j) = d] f(d)=i=1∑Nj=1∑M[gcd(i,j)=d] F ( n ) = ∑ n ∣ d f ( d ) F(n) = \sum\limits_{n|d}f(d) F(n)=n∣d∑f(d)由 F ( n ) F(n) F(n)定义可知, F ( n ) = ⌊ N n ⌋ ⌊ M n ⌋ F(n) = \lfloor \frac{N}{n}\rfloor \lfloor \frac{M}{n} \rfloor F(n)=⌊nN⌋⌊nM⌋
答案为:
∑
p
∈
p
r
i
m
e
s
f
(
p
)
\sum\limits_{p \in primes } f(p)
p∈primes∑f(p)莫比乌斯反演:
∑
p
∈
p
r
i
m
e
s
∑
p
∣
d
μ
(
d
p
)
F
(
d
)
\sum\limits_{p \in primes}\sum\limits_{p|d} \mu(\frac{d}{p})F(d)
p∈primes∑p∣d∑μ(pd)F(d)令
d
1
=
d
p
d_1 = \frac{d}{p}
d1=pd:
∑
p
∈
p
r
i
m
e
s
∑
d
1
=
1
m
i
n
(
⌊
N
p
⌋
,
⌊
M
p
⌋
)
μ
(
d
1
)
F
(
d
1
p
)
\sum\limits_{p \in primes}\sum\limits_{d_1 = 1} \limits^{min(\lfloor \frac{N}{p}\rfloor,\lfloor \frac{M}{p}\rfloor)}\mu(d_1)F(d_1p)
p∈primes∑d1=1∑min(⌊pN⌋,⌊pM⌋)μ(d1)F(d1p)代入
F
(
d
1
p
)
F(d_1p)
F(d1p):
∑
p
∈
p
r
i
m
e
s
∑
d
1
=
1
m
i
n
(
⌊
N
p
⌋
,
⌊
M
p
⌋
)
μ
(
d
1
)
⌊
N
d
1
p
⌋
⌊
M
d
1
p
⌋
\sum\limits_{p \in primes}\sum\limits_{d_1 = 1} \limits^{min(\lfloor \frac{N}{p}\rfloor,\lfloor \frac{M}{p}\rfloor)}\mu(d_1)\lfloor \frac{N}{d_1p}\rfloor\lfloor \frac{M}{d_1p}\rfloor
p∈primes∑d1=1∑min(⌊pN⌋,⌊pM⌋)μ(d1)⌊d1pN⌋⌊d1pM⌋令
T
=
d
1
p
T = d_1p
T=d1p:
∑
T
=
1
m
i
n
(
N
,
M
)
∑
t
∣
T
,
t
∈
p
r
i
m
e
s
μ
(
⌊
T
t
⌋
)
⌊
N
T
⌋
⌊
M
T
⌋
\sum\limits_{T=1}\limits^{min(N,M)}\sum\limits_{t|T,t\in primes}\mu(\lfloor \frac{T}{t} \rfloor)\lfloor \frac{N}{T}\rfloor\lfloor \frac{M}{T}\rfloor
T=1∑min(N,M)t∣T,t∈primes∑μ(⌊tT⌋)⌊TN⌋⌊TM⌋
∑
T
=
1
m
i
n
(
N
,
M
)
⌊
N
T
⌋
⌊
M
T
⌋
∑
t
∣
T
,
t
∈
p
r
i
m
e
s
μ
(
⌊
T
t
⌋
)
\sum\limits_{T=1}\limits^{min(N,M)} \lfloor \frac{N}{T}\rfloor\lfloor \frac{M}{T}\rfloor\sum\limits_{t|T,t\in primes}\mu(\lfloor \frac{T}{t} \rfloor)
T=1∑min(N,M)⌊TN⌋⌊TM⌋t∣T,t∈primes∑μ(⌊tT⌋)
前边可以整除分块,后边可以预处理前缀和
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e7+10;
int mu[maxn], prime[maxn], vis[maxn];
int tot;
ll sum[maxn], f[maxn];
inline ll read(){//读入优化
char ch;
while((ch=getchar())<'0'||ch>'9');
ll res = ch-48;
while((ch=getchar())>='0'&&ch<='9')
res = res*10+ch-48;
return res;
}
void get_mu(int n){
mu[1] = 1;
for(int i = 2; i <= n; i++){
if(!vis[i]){
prime[++tot] = i;
mu[i] = -1;
}
for(int j = 1; j <= tot && i*prime[j] <= n; j++){
vis[i*prime[j]] = 1;
if(i % prime[j] == 0){
mu[i*prime[j]] = 0;
break;
}
else
mu[i*prime[j]] = -mu[i];
}
}
for(int j = 1; j <= tot; j++){
for(int i = 1; i*prime[j] <= n; i++){
f[i*prime[j]] += mu[i];
}
}
for(int i = 1; i <= n; i++)
sum[i] = sum[i-1]+f[i];
}
int N, M;
void solve(){
ll res = 0;
//scanf("%lld %lld", &N, &M);
//cin >> N >> M;
N = read(), M = read();
if(N > M)
swap(N, M);
int r;
for(int l = 1; l <= N; l = r+1){
r = min(N/(N/l), M/(M/l));
res += 1ll*(N/l)*(M/l)*(sum[r]-sum[l-1]);
}
printf("%lld\n", res);
//cout << res << endl;
}
signed main(){
int T;
cin >> T;
get_mu(10000000);
while(T--)
solve();
return 0;
}
ZAP-Queries
题意:
∑ i = 1 a ∑ j = 1 b [ g c d ( i , j ) = k ] \sum\limits_{i=1}\limits^{a}\sum\limits_{j=1}\limits^{b}[gcd(i,j) = k] i=1∑aj=1∑b[gcd(i,j)=k]
解析:
∑
i
=
1
a
∑
j
=
1
b
[
g
c
d
(
i
,
j
)
=
k
]
\sum\limits_{i=1}\limits^{a}\sum\limits_{j=1}\limits^{b}[gcd(i,j) = k]
i=1∑aj=1∑b[gcd(i,j)=k]
∑
i
=
1
⌊
a
k
⌋
∑
j
=
1
⌊
b
k
⌋
[
g
c
d
(
i
,
j
)
=
1
]
\sum\limits_{i=1}\limits^{\lfloor\frac{a}{k}\rfloor}\sum\limits_{j=1}\limits^{\lfloor\frac{b}{k}\rfloor}[gcd(i,j) = 1]
i=1∑⌊ka⌋j=1∑⌊kb⌋[gcd(i,j)=1]
∑
i
=
1
⌊
a
k
⌋
∑
j
=
1
⌊
b
k
⌋
∑
d
∣
g
c
d
(
i
,
j
)
μ
(
d
)
\sum\limits_{i=1}\limits^{\lfloor\frac{a}{k}\rfloor}\sum\limits_{j=1}\limits^{\lfloor\frac{b}{k}\rfloor}\sum\limits_{d|gcd(i,j)}\mu(d)
i=1∑⌊ka⌋j=1∑⌊kb⌋d∣gcd(i,j)∑μ(d)
∑
i
=
1
⌊
a
k
⌋
∑
j
=
1
⌊
b
k
⌋
∑
d
=
1
⌊
a
k
⌋
μ
(
d
)
[
d
∣
g
c
d
(
i
,
j
)
]
\sum\limits_{i=1}\limits^{\lfloor\frac{a}{k}\rfloor}\sum\limits_{j=1}\limits^{\lfloor\frac{b}{k}\rfloor}\sum\limits_{d=1}\limits^{\lfloor\frac{a}{k}\rfloor}\mu(d)[d|gcd(i,j)]
i=1∑⌊ka⌋j=1∑⌊kb⌋d=1∑⌊ka⌋μ(d)[d∣gcd(i,j)]将
μ
(
d
)
提前:
\mu(d)提前:
μ(d)提前:
∑
d
=
1
⌊
a
k
⌋
μ
(
d
)
∑
i
=
1
⌊
a
k
⌋
∑
j
=
1
⌊
b
k
⌋
[
d
∣
g
c
d
(
i
,
j
)
]
\sum\limits_{d=1}\limits^{\lfloor\frac{a}{k}\rfloor}\mu(d)\sum\limits_{i=1}\limits^{\lfloor\frac{a}{k}\rfloor}\sum\limits_{j=1}\limits^{\lfloor\frac{b}{k}\rfloor}[d|gcd(i,j)]
d=1∑⌊ka⌋μ(d)i=1∑⌊ka⌋j=1∑⌊kb⌋[d∣gcd(i,j)]
∑
d
=
1
⌊
a
k
⌋
μ
(
d
)
⌊
a
k
d
⌋
⌊
b
k
d
⌋
\sum\limits_{d=1}\limits^{\lfloor\frac{a}{k}\rfloor}\mu(d)\lfloor\frac{a}{kd}\rfloor\lfloor\frac{b}{kd}\rfloor
d=1∑⌊ka⌋μ(d)⌊kda⌋⌊kdb⌋
同上,后面部分可以整除分块,前面部分可以预处理前缀和
#include<iostream>
using namespace std;
typedef long long ll;
const int maxn = 5e4+10;
int vis[maxn], prime[maxn], tot;
int mu[maxn], sum[maxn];
void get_mu(int n){
mu[1] = 1;
for(int i = 2; i <= n; i++){
if(!vis[i]){
prime[++tot] = i;
mu[i] = -1;
}
for(int j = 1; j <= tot && i*prime[j] <= n; j++){
vis[i*prime[j]] = 1;
if(i%prime[j] == 0){
mu[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];
}
int a, b, d;
void solve(){
cin >> a >> b >> d;
if(a > b)
swap(a, b);
a = a/d, b = b/d;
ll res = 0;
int r = 0;
for(int l = 1; l <= a; l = r+1){
r = min(a/(a/l), b/(b/l));
res += 1ll*(a/l)*(b/l)*(sum[r]-sum[l-1]);
}
printf("%lld\n", res);
return ;
}
int main(){
get_mu(50000);
int T;
cin >> T;
while(T--)
solve();
return 0;
}
Problem b
题意:
∑ i = a b ∑ j = c d [ g c d ( i , j ) = k ] \sum\limits_{i=a}\limits^{b}\sum\limits_{j=c}\limits^{d}[gcd(i,j) = k] i=a∑bj=c∑d[gcd(i,j)=k]
解析:
同上题,先求出 ∑ i = 1 a ∑ j = 1 b [ g c d ( i , j ) = k ] \sum\limits_{i=1}\limits^{a}\sum\limits_{j=1}\limits^{b}[gcd(i,j) = k] i=1∑aj=1∑b[gcd(i,j)=k] 的答案,然后容斥一下
代码:
#include<iostream>
using namespace std;
typedef long long ll;
const int maxn = 5e4+10;
int vis[maxn], prime[maxn], tot;
int mu[maxn], sum[maxn];
void get_mu(int n){
mu[1] = 1;
for(int i = 2; i <= n; i++){
if(!vis[i]){
prime[++tot] = i;
mu[i] = -1;
}
for(int j = 1; j <= tot && i*prime[j] <= n; j++){
vis[i*prime[j]] = 1;
if(i%prime[j] == 0){
mu[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];
}
int a, b, c, d, k;
ll ans;
ll solve(int a, int b, int k){
//cin >> a >> b >> d;
if(a > b)
swap(a, b);
a = a/k, b = b/k;
ll res = 0;
int r = 0;
for(int l = 1; l <= a; l = r+1){
r = min(a/(a/l), b/(b/l));
res += 1ll*(a/l)*(b/l)*(sum[r]-sum[l-1]);
}
//printf("%lld\n", res);
return res;
}
int main(){
get_mu(50000);
int T;
cin >> T;
while(T--){
cin >> a >> b >> c >> d >> k;
ans = solve(b, d, k)-solve(a-1, d, k)-solve(b, c-1, k)+solve(a-1, c-1, k);
printf("%lld\n", ans);
}
return 0;
}
https://www.cnblogs.com/peng-ym/p/8652288.html
https://oi-wiki.org/math/number-theory/mobius/