虽然题目上写了反演但是我不知道什么是反演……如果你把Sigma调换位置叫做反演的话。
这道题题面非常简单:
设
d
(
x
)
d(x)
d(x)为正整数
x
x
x的约数个数,给定
N
,
M
N, M
N,M,
求
∑
i
=
1
N
∑
j
=
1
M
d
(
i
j
)
\sum_{i=1}^N\sum_{j=1}^Md(ij)
i=1∑Nj=1∑Md(ij)
当时我too naive,看到这玩意就默默地打50分暴力去了。。。
今天江苏神犇们做了这道题,我顺便听明白了~~
首先它不知用什么精妙的办法(可能我以后会知道),推出了
∑
i
=
1
N
∑
j
=
1
M
d
(
i
j
)
=
∑
i
=
1
N
∑
j
=
1
M
⌊
N
i
⌋
⌊
M
i
⌋
[
g
c
d
(
i
,
j
)
=
=
1
]
\sum_{i=1}^N\sum_{j=1}^Md(ij)= \sum_{i=1}^N\sum_{j=1}^M\left\lfloor\frac Ni\right\rfloor\left\lfloor\frac Mi\right\rfloor[gcd(i,j)==1]
i=1∑Nj=1∑Md(ij)=i=1∑Nj=1∑M⌊iN⌋⌊iM⌋[gcd(i,j)==1]
证明办法是做二阶差分,
记
F
(
N
,
M
)
:
=
∑
i
=
1
N
∑
j
=
1
M
d
(
i
j
)
,
G
(
N
,
M
)
:
=
∑
i
=
1
N
∑
j
=
1
M
⌊
N
i
⌋
⌊
M
i
⌋
[
g
c
d
(
i
,
j
)
=
=
1
]
=
∑
i
=
1
∞
∑
j
=
1
∞
⌊
N
i
⌋
⌊
M
i
⌋
[
g
c
d
(
i
,
j
)
=
=
1
]
(
这
两
个
等
价
,
∵
∀
i
(
>
N
)
,
⌊
N
/
i
⌋
=
=
0
)
\begin{aligned} F(N,M)&:=\sum_{i=1}^N\sum_{j=1}^Md(ij)\, ,\\ G(N,M)&:=\sum_{i=1}^N\sum_{j=1}^M\left\lfloor\frac Ni\right\rfloor\left\lfloor\frac Mi\right\rfloor[gcd(i,j)==1] \\ &=\sum_{i=1}^{\infty}\sum_{j=1}^\infty\left\lfloor\frac Ni\right\rfloor\left\lfloor\frac Mi\right\rfloor[gcd(i,j)==1]\,(这两个等价,\because \forall i(>N), \lfloor N/i\rfloor==0) \end{aligned}
F(N,M)G(N,M):=i=1∑Nj=1∑Md(ij),:=i=1∑Nj=1∑M⌊iN⌋⌊iM⌋[gcd(i,j)==1]=i=1∑∞j=1∑∞⌊iN⌋⌊iM⌋[gcd(i,j)==1](这两个等价,∵∀i(>N),⌊N/i⌋==0)
则(二阶差分在这里)
d
(
N
×
M
)
=
F
(
N
,
M
)
−
F
(
N
−
1
,
M
)
−
F
(
N
,
M
−
1
)
+
F
(
N
−
1
,
M
−
1
)
\begin{aligned} d(N\times M)=F(N,M)&-F(N-1,M)\\ &-F(N,M-1)+F(N-1,M-1) \end{aligned}
d(N×M)=F(N,M)−F(N−1,M)−F(N,M−1)+F(N−1,M−1)
G
(
N
,
M
)
−
G
(
N
−
1
,
M
)
−
G
(
N
,
M
−
1
)
+
G
(
N
−
1
,
M
−
1
)
=
∑
i
=
1
∞
∑
j
=
1
∞
(
⌊
N
i
⌋
−
⌊
N
−
1
i
⌋
)
(
⌊
M
i
⌋
−
⌊
M
−
1
i
⌋
)
[
g
c
d
(
i
,
j
)
=
=
1
]
\begin{aligned} &G(N,M)-G(N-1,M)-G(N,M-1)+G(N-1,M-1) \\=&\sum_{i=1}^{\infty}\sum_{j=1}^\infty \left(\left\lfloor\frac Ni\right\rfloor-\left\lfloor\frac {N-1}i\right\rfloor\right) \left(\left\lfloor\frac Mi\right\rfloor-\left\lfloor\frac {M-1}i\right\rfloor\right) [gcd(i,j)==1] \end{aligned}
=G(N,M)−G(N−1,M)−G(N,M−1)+G(N−1,M−1)i=1∑∞j=1∑∞(⌊iN⌋−⌊iN−1⌋)(⌊iM⌋−⌊iM−1⌋)[gcd(i,j)==1]
考虑G的二阶差分的意义。
(
⌊
N
i
⌋
−
⌊
N
−
1
i
⌋
)
\left(\left\lfloor\frac Ni\right\rfloor-\left\lfloor\frac {N-1}i\right\rfloor\right)
(⌊iN⌋−⌊iN−1⌋)只有当
i
∣
N
i|N
i∣N的时候才为
1
1
1,
(
⌊
M
i
⌋
−
⌊
M
−
1
i
⌋
)
\left(\left\lfloor\frac Mi\right\rfloor-\left\lfloor\frac {M-1}i\right\rfloor\right)
(⌊iM⌋−⌊iM−1⌋)同理。
即G的二阶差分可理解为满足
1
≤
i
≤
N
,
1
≤
j
≤
M
,
g
c
d
(
i
,
j
)
=
=
1
,
且
i
∣
N
,
j
∣
M
1\le i \le N,1 \le j \le M,gcd(i,j)==1,且i|N,j|M
1≤i≤N,1≤j≤M,gcd(i,j)==1,且i∣N,j∣M的有序数对
(
i
,
j
)
(i,j)
(i,j)的个数。由于
i
,
j
i, j
i,j分别是
N
,
M
N, M
N,M的约数,因此对于任意两个不同的质因子
p
,
q
p, q
p,q,
i
,
j
i, j
i,j的选择方案是互不影响的。
因此,可考虑
N
×
M
N\times M
N×M的任一质因子
p
p
p,设
x
,
y
x, y
x,y分别是满足
p
x
∣
i
,
p
y
∣
j
p^x|i,p^y|j
px∣i,py∣j的最大整数。可以得出,质因子
p
p
p在等式左边的选法数为
x
+
y
+
1
x+y+1
x+y+1,而在等式右边的选法数也是
x
+
y
+
1
x+y+1
x+y+1(当
i
,
j
i,j
i,j其中任意一者含有质因子
p
p
p时,另一个就不可以含有质因子
p
p
p)。
故等式成立。
继续对该式进行变换(不失一般性,设
N
≤
M
N\le M
N≤M),
F
(
N
,
M
)
=
G
(
N
,
M
)
=
∑
i
=
1
N
∑
j
=
1
M
⌊
N
i
⌋
⌊
M
i
⌋
[
g
c
d
(
i
,
j
)
=
=
1
]
=
∑
i
=
1
N
∑
j
=
1
M
⌊
N
i
⌋
⌊
M
i
⌋
∑
d
∣
g
c
d
(
i
,
j
)
μ
(
d
)
=
∑
d
=
1
N
μ
(
d
)
∑
i
=
1
⌊
N
/
d
⌋
∑
j
=
1
⌊
M
/
d
⌋
⌊
N
i
d
⌋
⌊
M
j
d
⌋
=
∑
d
=
1
N
μ
(
d
)
∑
i
=
1
⌊
N
/
d
⌋
⌊
N
i
d
⌋
∑
j
=
1
⌊
M
/
d
⌋
⌊
M
j
d
⌋
\begin{aligned} F(N,M)&=G(N,M) \\ &=\sum_{i=1}^N\sum_{j=1}^M\left\lfloor\frac Ni\right\rfloor\left\lfloor\frac Mi\right\rfloor[gcd(i,j)==1] \\ &=\sum_{i=1}^N\sum_{j=1}^M\left\lfloor\frac Ni\right\rfloor\left\lfloor\frac Mi\right\rfloor\sum_{d|gcd(i,j)}\mu(d) \\ &=\sum_{d=1}^N\mu(d)\sum_{i=1}^{\lfloor N/d\rfloor}\sum_{j=1}^{\lfloor M/d\rfloor}\left\lfloor\frac N{id}\right\rfloor\left\lfloor\frac M{jd}\right\rfloor \\ &=\sum_{d=1}^N\mu(d)\sum_{i=1}^{\lfloor N/d\rfloor}\left\lfloor\frac N{id}\right\rfloor\sum_{j=1}^{\lfloor M/d\rfloor}\left\lfloor\frac M{jd}\right\rfloor \end{aligned}
F(N,M)=G(N,M)=i=1∑Nj=1∑M⌊iN⌋⌊iM⌋[gcd(i,j)==1]=i=1∑Nj=1∑M⌊iN⌋⌊iM⌋d∣gcd(i,j)∑μ(d)=d=1∑Nμ(d)i=1∑⌊N/d⌋j=1∑⌊M/d⌋⌊idN⌋⌊jdM⌋=d=1∑Nμ(d)i=1∑⌊N/d⌋⌊idN⌋j=1∑⌊M/d⌋⌊jdM⌋
记
g
(
n
)
:
=
∑
i
=
1
n
⌊
n
i
⌋
g(n):=\sum_{i=1}^n\left\lfloor\frac ni\right\rfloor
g(n):=i=1∑n⌊in⌋
则
F
(
N
,
M
)
F(N,M)
F(N,M)可进一步化简为
F
(
N
,
M
)
=
∑
d
=
1
N
μ
(
d
)
g
(
⌊
N
i
d
⌋
)
g
(
⌊
M
j
d
⌋
)
F(N,M)=\sum_{d=1}^N\mu(d)g\left(\left\lfloor\frac N{id}\right\rfloor\right)g\left(\left\lfloor\frac M{jd}\right\rfloor\right)
F(N,M)=d=1∑Nμ(d)g(⌊idN⌋)g(⌊jdM⌋)
可以发现
g
g
g函数其实就是
d
d
d函数的前缀和,于是可以线性筛出来。
至于约数个数怎么线性筛,只要记录一下每个数,他的素因子分解式中最小素因子的次数c[i]
即可。
void genPrime(int n){
memset(isprime,true,sizeof isprime);
mu[1]=d[1]=c[1]=1;
for(int i=2;i<=n;++i){
if(isprime[i]){
prime[tot++]=i;
mu[i]=-1;
c[i]=1;
d[i]=2;
}
for(int j=0;j<tot&&i*prime[j]<=n;++j){
isprime[i*prime[j]]=false;
if(i%prime[j]==0){
d[i*prime[j]]=d[i]/(c[i]+1)*(c[i]+2);
c[i*prime[j]]=c[i]+1;break;
}
mu[i*prime[j]]=-mu[i];
d[i*prime[j]]=d[i]*d[prime[j]];
c[i*prime[j]]=1;
}
}
}
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long ll;
int gcd(int a,int b){return b?gcd(b,a%b):a;}
const int maxn=50001;
int tot,prime[30001],mu[maxn],c[maxn];
ll d[maxn];
bool isprime[maxn];
ll Ans[101][101];
void genPrime(int n){
memset(isprime,true,sizeof isprime);
mu[1]=d[1]=c[1]=1;
for(int i=2;i<=n;++i){
if(isprime[i]){
prime[tot++]=i;
mu[i]=-1;
c[i]=1;
d[i]=2;
}
for(int j=0;j<tot&&i*prime[j]<=n;++j){
isprime[i*prime[j]]=false;
if(i%prime[j]==0){
d[i*prime[j]]=d[i]/(c[i]+1)*(c[i]+2);
c[i*prime[j]]=c[i]+1;break;
}
mu[i*prime[j]]=-mu[i];
d[i*prime[j]]=d[i]*d[prime[j]];
c[i*prime[j]]=1;
}
}
for(int i=1;i<=n;++i) mu[i]+=mu[i-1];
for(int i=1;i<=n;++i) d[i]+=d[i-1];
}
inline int read(){
int x=0;char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) x=x*10+ch-48,ch=getchar();
return x;
}
char a[18];
inline void print(ll x){
a[0]=0;
while(x) a[++a[0]]=x%10,x/=10;
for(;a[0];--a[0])
putchar(a[a[0]]+48);
putchar('\n');
}
int main(){
genPrime(50000);
int t=read();
while(t--){
int n=read(),m=read();
if(n<=100&&m<=100){
if(Ans[n][m]){
print(Ans[n][m]);
continue;
}
}
if(n>m) swap(n,m);
ll ans=0;
for(int i=1,nex;i<=n;i=nex+1){
nex=min(n/(n/i),m/(m/i));
ans+=(mu[nex]-mu[i-1])*d[n/i]*d[m/i];
}
if(n<=100&&m<=100) Ans[n][m]=Ans[m][n]=ans;
print(ans);
}
return 0;
}