0:前置知识
线性筛积性函数
int mu[N],prime[N],tot=0;
int v[N];
void sieve()
{
mu[1]=1;
for(int i=2;i<=n;i++)
{
if(!v[i])
{
v[i]=i;
prime[++tot]=i;
mu[i]=-1;
}
for(int j=1;j<=tot;j++)
{
if(prime[j]>v[i]||i*prime[j]>n) break;
v[i*prime[j]]=prime[j];
if(i%prime[j]==0)
{
mu[i*prime[j]]=0;
break;
}
else mu[i*prime[j]]=mu[i]*mu[prime[j]];
}
}
}
整除分块
int l,r;
int ans=0;
for(;l<=r;l=r+1)
{
r=(n/(n/l));
ans+=(r-l+1)*(n/l);
}
莫比乌斯函数
记
μ
(
n
)
\mu (n)
μ(n)为
n
n
n的莫比乌斯函数,其中
n
=
Π
p
i
c
i
n=\Pi_{p_i}^{c_i}
n=Πpici
则若
c
i
c_i
ci不等于1,
μ
(
n
)
=
0
\mu(n)=0
μ(n)=0
若
p
i
p_i
pi的个数为
k
k
k,则
μ
(
n
)
=
(
−
1
)
k
\mu(n)=(-1)^k
μ(n)=(−1)k
特殊的,
μ
(
1
)
=
1
\mu(1)=1
μ(1)=1
性质:
∑
d
∣
n
μ
(
d
)
=
[
n
=
=
1
]
\sum_{d|n}\mu(d)=[n==1]
∑d∣nμ(d)=[n==1]
μ
(
n
)
=
−
∑
d
∣
n
,
d
!
=
n
μ
(
d
)
)
\mu(n)=-\sum_{d|n ,d!=n}\mu(d))
μ(n)=−∑d∣n,d!=nμ(d))
μ
(
n
)
=
μ
(
a
)
μ
(
b
)
\mu(n)=\mu(a)\mu(b)
μ(n)=μ(a)μ(b),其中
n
=
a
×
b
n=a\times b
n=a×b,且
g
c
d
(
a
,
b
)
=
1
gcd(a,b)=1
gcd(a,b)=1
狄雷克雷卷积
h
(
n
)
=
∑
d
∣
n
f
(
n
)
g
(
n
/
d
)
h(n)=\sum _{d|n}f(n)g(n/d)
h(n)=d∣n∑f(n)g(n/d)
则
h
h
h为
g
g
g和
f
f
f的狄利克雷卷积,记作
h
=
f
×
g
h=f\times g
h=f×g
记
e
(
n
)
e(n)
e(n)为元函数,表示
e
(
n
)
=
[
n
=
=
1
]
e(n)=[n==1]
e(n)=[n==1]
记
i
d
(
n
)
id(n)
id(n)为单位函数,表示
i
d
(
n
)
=
n
id(n)=n
id(n)=n
记
I
(
n
)
I(n)
I(n)为恒等函数,表示
I
(
n
)
=
1
I(n)=1
I(n)=1
几个性质
1:
f
×
g
=
g
×
f
f\times g=g\times f
f×g=g×f:交换律
2:
f
×
g
×
h
=
f
×
(
g
×
h
)
f\times g\times h=f\times (g\times h)
f×g×h=f×(g×h)
3:
f
×
e
=
f
f\times e=f
f×e=f:因为如果
n
/
d
n/d
n/d不等于1,式子为0,而此时式子的值为
f
(
n
)
f(n)
f(n)
4:
μ
×
I
=
e
\mu \times I=e
μ×I=e:
∑
d
∣
n
μ
(
d
)
=
[
n
=
=
1
]
\sum_{d|n}\mu(d)=[n==1]
∑d∣nμ(d)=[n==1]
5:
φ
×
I
=
i
d
\varphi \times I= id
φ×I=id:
∑
d
∣
n
φ
(
d
)
=
n
\sum_{d|n}\varphi(d)=n
∑d∣nφ(d)=n
6:
φ
=
μ
×
i
d
\varphi=\mu\times id
φ=μ×id
证明:将5式的两边同时卷上
μ
\mu
μ,由之前的性质可得,
φ
=
μ
×
i
d
\varphi =\mu \times id
φ=μ×id
莫比乌斯反演
反演公式:记
f
(
n
)
=
∑
d
∣
n
g
(
n
)
f(n)=\sum_{d|n}g(n)
f(n)=∑d∣ng(n)
则
g
(
n
)
=
∑
d
∣
n
f
(
d
)
μ
(
n
/
d
)
g(n)=\sum_{d|n}f(d)\mu(n/d)
g(n)=∑d∣nf(d)μ(n/d)
原理:
f
=
g
×
I
f = g\times I
f=g×I
f
×
μ
=
g
×
e
f\times \mu=g \times e
f×μ=g×e
g
=
f
×
μ
g=f\times \mu
g=f×μ
例题
1:周期性的字符串
对于长度为n、由小写字母组成的(不一定要用所有字母)字符串s,如果存在一个字符串t,t≠s,使得s可以由t重复若干次恰好得到(不能有多余字符),那么我们称s具有周期性。
周期性字符串计数问题是指对于给定的n,求有多少个长度为n的周期性字符串。答案比较大,只需要输出对
1
0
9
+
7
10^9+7
109+7取余即可。
注意串中只包含26个小写字母。
分析
设
f
(
n
)
f(n)
f(n)表示长度为
n
n
n的字符串个数之和,则
f
(
n
)
=
2
6
n
f(n)=26^n
f(n)=26n
设
g
(
n
)
g(n)
g(n)表示长度为
n
n
n,且没有周期性为(或者说周期为1)的字符串个数
则长度为n的字符串可以看成长度为d的字符串重复出现
n
/
d
n/d
n/d次形成的
即
f
(
n
)
=
∑
d
∣
n
g
(
n
)
f(n)=\sum_{d|n}g(n)
f(n)=∑d∣ng(n)
由莫比乌斯反演公式可知
g
(
n
)
=
∑
d
∣
n
f
(
d
)
μ
(
n
/
d
)
g(n)=\sum_{d|n}f(d)\mu(n/d)
g(n)=∑d∣nf(d)μ(n/d)
我们求出
g
(
n
)
g(n)
g(n),则题目所求的就是周期不为1的字符串个数,我们用总的字符串数量减掉周期为1,长度为n的字符串就是题目所求
也就是
f
(
n
)
−
g
(
n
)
f(n)-g(n)
f(n)−g(n)
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 1e9+7;
const int N = 1e6+7;
int mu[N],prime[N],tot=0;
int v[N];
LL Pow[N];
void init(int n)
{
mu[1]=1;
for(int i=2;i<=n;i++)
{
if(!v[i])
{
v[i]=i;
prime[++tot]=i;
mu[i]=-1;
}
for(int j=1;j<=tot;j++)
{
if(prime[j]>v[i]||i*prime[j]>n) break;
v[i*prime[j]]=prime[j];
if(i%prime[j]==0)
{
mu[i*prime[j]]=0;
break;
}
else mu[i*prime[j]]=mu[i]*mu[prime[j]];
}
}
Pow[0]=1;
for(int i=1;i<=n;i++)
Pow[i]=1ll*Pow[i-1]*26%mod;
}
LL f(int n)
{
return Pow[n];
}
LL g(int n)
{
LL ans=0;
for(int d=1;d<=n;d++)
if(n%d==0) ans=(ans+f(d)*mu[n/d]%mod)%mod;
return ans;
}
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
LL n;
cin>>n;
init(n);
cout<<((f(n)-g(n))%mod+mod)%mod;
return 0;
}
2:互质数对
求
∑
i
=
1
n
∑
j
=
1
n
[
g
c
d
(
i
,
j
)
=
=
1
]
\sum_{i=1}^n\sum_{j=1}^n[gcd(i,j)==1]
∑i=1n∑j=1n[gcd(i,j)==1]
因为
∑
d
∣
n
μ
(
d
)
=
[
n
=
=
1
]
\sum_{d|n}\mu(d)=[n==1]
∑d∣nμ(d)=[n==1]
把
n
n
n换成
g
c
d
(
i
,
j
)
gcd(i,j)
gcd(i,j)可知,所求为
∑
i
=
1
n
∑
j
=
1
n
∑
d
∣
i
,
d
∣
j
μ
(
d
)
\sum_{i=1}^n\sum_{j=1}^n\sum_{d|i,d|j}\mu(d)
∑i=1n∑j=1n∑d∣i,d∣jμ(d)
将
d
d
d提前,
∑
d
=
1
n
μ
(
d
)
∑
d
∣
i
∑
d
∣
j
1
\sum_{d=1}^n\mu(d)\sum_{d|i}\sum_{d|j}1
∑d=1nμ(d)∑d∣i∑d∣j1
把
i
,
j
i,j
i,j换成倍数可得
∑
d
=
1
n
μ
(
d
)
∑
i
=
1
⌊
n
d
⌋
∑
j
=
1
⌊
n
d
⌋
\sum_{d=1}^n\mu(d)\sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{n}{d} \rfloor}
d=1∑nμ(d)i=1∑⌊dn⌋j=1∑⌊dn⌋
=
∑
d
=
1
n
μ
(
d
)
⌊
n
d
⌋
⌊
n
d
⌋
=\sum_{d=1}^n\mu(d)\lfloor \frac{n}{d} \rfloor \lfloor \frac{n}{d} \rfloor
=d=1∑nμ(d)⌊dn⌋⌊dn⌋
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e7+7;
LL mu[N];
int prime[N],tot=0;
int v[N];
void init(int n)
{
mu[1]=1;
for(int i=2;i<=n;i++)
{
if(!v[i])
{
v[i]=i;
prime[++tot]=i;
mu[i]=-1;
}
for(int j=1;j<=tot;j++)
{
if(prime[j]>v[i]||i*prime[j]>n) break;
v[i*prime[j]]=prime[j];
if(i%prime[j]==0)
{
mu[i*prime[j]]=0;
break;
}
else mu[i*prime[j]]=mu[i]*mu[prime[j]];
}
}
for(int i=1;i<=n;i++)
mu[i]=mu[i-1]+mu[i];
}
int main()
{
freopen("mu.in","r",stdin);
freopen("mu.out","w",stdout);
int n;
cin>>n;
init(n);
LL ans=0;
int l=1,r;
for(;l<=n;l=r+1)
{
r=(n/(n/l));
ans=(ans+(mu[r]-mu[l-1])*(n/l)*(n/l));
}
cout<<ans;
return 0;
}
【BZOJ2693】jzptab
求 ∑ i = 1 n ∑ j = 1 m l c m ( i , j ) \sum_{i=1}^n\sum_{j=1}^mlcm(i,j) i=1∑nj=1∑mlcm(i,j)
思路
记
S
(
n
)
=
∑
i
=
1
n
i
S(n)=\sum_{i=1}^ni
S(n)=∑i=1ni
∑
i
=
1
n
∑
j
=
1
m
l
c
m
(
i
,
j
)
=
∑
i
=
1
n
∑
j
=
1
m
i
j
g
c
d
(
i
,
j
)
\sum_{i=1}^n\sum_{j=1}^mlcm(i,j)=\sum_{i=1}^n\sum_{j=1}^m\frac{ij}{gcd(i,j)}
i=1∑nj=1∑mlcm(i,j)=i=1∑nj=1∑mgcd(i,j)ij
=
∑
i
=
1
n
∑
j
=
1
m
∑
d
∣
i
,
d
∣
j
[
g
c
d
(
i
,
j
)
=
=
d
]
i
j
d
=\sum_{i=1}^n\sum_{j=1}^m\sum_{d|i,d|j}[gcd(i,j)==d]\frac{ij}{d}
=i=1∑nj=1∑md∣i,d∣j∑[gcd(i,j)==d]dij
=
∑
d
=
1
n
∑
d
∣
i
∑
d
∣
j
[
g
c
d
(
i
,
j
)
=
=
d
]
i
j
d
= \sum_{d=1}^n\sum_{d|i}\sum_{d|j}[gcd(i,j)==d]\frac{ij}{d}
=d=1∑nd∣i∑d∣j∑[gcd(i,j)==d]dij
=
∑
d
=
1
n
∑
i
=
1
⌊
n
d
⌋
∑
j
=
1
⌊
m
d
⌋
[
g
c
d
(
i
,
j
)
=
=
1
]
i
j
d
2
d
= \sum_{d=1}^n\sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{m}{d} \rfloor}[gcd(i,j)==1]\frac{ijd^2}{d}
=d=1∑ni=1∑⌊dn⌋j=1∑⌊dm⌋[gcd(i,j)==1]dijd2
=
∑
d
=
1
n
d
∑
i
=
1
⌊
n
d
⌋
i
∑
j
=
1
⌊
m
d
⌋
j
∑
k
∣
i
,
k
∣
j
μ
(
k
)
= \sum_{d=1}^nd\sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}i\sum_{j=1}^{\lfloor \frac{m}{d} \rfloor}j\sum_{k|i,k|j}\mu(k)
=d=1∑ndi=1∑⌊dn⌋ij=1∑⌊dm⌋jk∣i,k∣j∑μ(k)
=
∑
d
=
1
n
d
∑
k
=
1
⌊
n
d
⌋
μ
(
k
)
∑
k
∣
i
⌊
n
d
⌋
i
∑
k
∣
j
⌊
m
d
⌋
j
= \sum_{d=1}^nd\sum_{k=1}^{\lfloor \frac{n}{d} \rfloor}\mu(k)\sum_{k|i}^{\lfloor \frac{n}{d} \rfloor}i\sum_{k|j}^{\lfloor \frac{m}{d} \rfloor}j
=d=1∑ndk=1∑⌊dn⌋μ(k)k∣i∑⌊dn⌋ik∣j∑⌊dm⌋j
=
∑
d
=
1
n
d
∑
k
=
1
⌊
n
d
⌋
μ
(
k
)
k
2
∑
i
=
1
⌊
n
d
k
⌋
i
∑
j
=
1
⌊
m
d
k
⌋
j
= \sum_{d=1}^nd\sum_{k=1}^{\lfloor \frac{n}{d} \rfloor}\mu(k)k^2\sum_{i=1}^{\lfloor \frac{n}{dk} \rfloor}i\sum_{j=1}^{\lfloor \frac{m}{dk} \rfloor}j
=d=1∑ndk=1∑⌊dn⌋μ(k)k2i=1∑⌊dkn⌋ij=1∑⌊dkm⌋j
=
∑
d
=
1
n
d
∑
k
=
1
⌊
n
d
⌋
μ
(
k
)
k
2
S
(
⌊
n
d
k
⌋
)
S
(
⌊
m
d
k
⌋
)
= \sum_{d=1}^nd\sum_{k=1}^{\lfloor \frac{n}{d} \rfloor}\mu(k)k^2S(\lfloor \frac{n}{dk} \rfloor)S(\lfloor \frac{m}{dk} \rfloor)
=d=1∑ndk=1∑⌊dn⌋μ(k)k2S(⌊dkn⌋)S(⌊dkm⌋)
=
∑
k
=
1
n
μ
(
k
)
k
2
∑
d
=
1
⌊
n
k
⌋
S
(
⌊
n
d
k
⌋
)
S
(
⌊
m
d
k
⌋
)
d
= \sum_{k=1}^n\mu(k)k^2\sum_{d=1}^{\lfloor \frac{n}{k} \rfloor}S(\lfloor \frac{n}{dk} \rfloor)S(\lfloor \frac{m}{dk} \rfloor)d
=k=1∑nμ(k)k2d=1∑⌊kn⌋S(⌊dkn⌋)S(⌊dkm⌋)d
=
∑
k
=
1
n
μ
(
k
)
k
2
∑
k
∣
T
n
S
(
⌊
n
T
⌋
)
S
(
⌊
m
T
⌋
)
T
k
= \sum_{k=1}^n\mu(k)k^2\sum_{k|T}^nS(\lfloor \frac{n}{T} \rfloor)S(\lfloor \frac{m}{T} \rfloor)\frac{T}{k}
=k=1∑nμ(k)k2k∣T∑nS(⌊Tn⌋)S(⌊Tm⌋)kT
=
∑
T
=
1
n
S
(
⌊
n
T
⌋
)
S
(
⌊
m
T
⌋
)
∑
k
∣
T
T
T
k
μ
(
k
)
k
2
= \sum_{T=1}^nS(\lfloor \frac{n}{T} \rfloor)S(\lfloor \frac{m}{T} \rfloor)\sum_{k|T}^T\frac{T}{k}\mu(k)k^2
=T=1∑nS(⌊Tn⌋)S(⌊Tm⌋)k∣T∑TkTμ(k)k2
=
∑
T
=
1
n
S
(
⌊
n
T
⌋
)
S
(
⌊
m
T
⌋
)
T
∑
k
∣
T
T
μ
(
k
)
k
= \sum_{T=1}^nS(\lfloor \frac{n}{T} \rfloor)S(\lfloor \frac{m}{T} \rfloor)T\sum_{k|T}^T\mu(k)k
=T=1∑nS(⌊Tn⌋)S(⌊Tm⌋)Tk∣T∑Tμ(k)k
记
f
(
n
)
=
n
∑
d
∣
n
μ
(
d
)
d
f(n)=n\sum_{d|n}\mu(d)d
f(n)=n∑d∣nμ(d)d
则
a
n
s
=
∑
T
=
1
n
S
(
⌊
n
T
⌋
)
S
(
⌊
m
T
⌋
)
f
(
T
)
ans= \sum_{T=1}^n\;S(\lfloor \frac{n}{T} \rfloor)S(\lfloor \frac{m}{T} \rfloor) f(T)
ans=T=1∑nS(⌊Tn⌋)S(⌊Tm⌋)f(T)
根据整除分块的相关知识
⌊
n
T
⌋
\lfloor \frac{n}{T} \rfloor
⌊Tn⌋的变化量只有
O
(
n
)
O(\sqrt n)
O(n)种,所以
S
(
⌊
n
T
⌋
)
S(\lfloor \frac{n}{T} \rfloor)
S(⌊Tn⌋)的变化量也有
O
(
n
)
O(\sqrt n)
O(n)种,处理剩余部分的前缀和,时间复杂度
O
(
n
+
T
n
)
O(n+T\sqrt n)
O(n+Tn),其中
T
T
T为询问次数
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod = 1e8+9;
const LL N = 1e7+7;
LL f[N];
LL v[N],prime[N],tot=0;
LL mu[N];
void init(LL n)
{
f[1]=1;
mu[1]=1;
for(LL i=2;i<=n;i++)
{
if(!v[i])
{
v[i]=i;
prime[++tot]=i;
mu[i]=-1;
f[i]=1+(-1)*i;
f[i]=(f[i]+mod)%mod;
}
for(LL j=1;j<=tot;j++)
{
if(prime[j]>v[i]||i*prime[j]>n) break;
v[prime[j]*i]=prime[j];
if(i%prime[j]==0)
{
f[prime[j]*i]=f[i]; //因为质因子的指数加一,所以新增的因子的莫比乌斯函数之都为0,所以相当于没有加
break;
}
else f[i*prime[j]]=(f[i]+(-1)*f[i]*prime[j]%mod+mod)%mod;
//新增一个质因子,这个质因子可以和之前的所有因子组合,也就是f[i]*prime[j],但是长度加一,莫比乌斯函数值变成相反数,所以要乘-1
}
}
for(LL i=1;i<=n;i++)
f[i]=(f[i]*i%mod+f[i-1])%mod;
}
LL S(LL n)
{
return 1ll*(1+n)*n/2%mod;
}
int main()
{
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
init(1e7);
LL T;
cin>>T;
while(T--)
{
LL n,m;
scanf("%lld %lld",&n,&m);
if(n>m) swap(n,m);
LL l=1,r;
LL ans=0;
for(;l<=n;l=r+1)
{
r=min((n/(n/l)),m/(m/l));
ans=(ans+S(n/l)*S(m/l)%mod*(f[r]-f[l-1]+mod)%mod)%mod;
}
printf("%lld\n",ans);
}
return 0;
}
[NOI2010day1]T1-能量采集
化简题意可知要求的是
∑
i
=
1
n
∑
j
=
1
m
2
×
g
c
d
(
i
,
j
)
−
1
\sum_{i=1}^n\sum_{j=1}^m2\times gcd(i,j)-1
i=1∑nj=1∑m2×gcd(i,j)−1
也就是
2
×
∑
i
=
1
n
∑
j
=
1
m
g
c
d
(
i
,
j
)
−
n
m
2\times \sum_{i=1}^n\sum_{j=1}^m gcd(i,j)-nm
2×i=1∑nj=1∑mgcd(i,j)−nm
而我们知道
n
=
∑
d
∣
n
φ
(
d
)
n=\sum_{d|n}\varphi (d)
n=∑d∣nφ(d)
把
g
c
d
(
i
,
j
)
gcd(i,j)
gcd(i,j)带入
n
n
n可得
∑
i
=
1
n
∑
j
=
1
m
∑
d
∣
i
,
d
∣
j
φ
(
d
)
\sum_{i=1}^{n}\sum_{j=1}^m\sum_{d|i,d|j}\varphi(d)
i=1∑nj=1∑md∣i,d∣j∑φ(d)
=
∑
d
=
1
n
φ
(
d
)
∑
d
∣
i
n
∑
d
∣
j
m
1
=\sum_{d=1}^n\varphi(d)\sum_{d|i}^{n}\sum_{d|j}^m1
=d=1∑nφ(d)d∣i∑nd∣j∑m1
=
∑
d
=
1
n
φ
(
d
)
∑
i
=
1
⌊
n
d
⌋
∑
j
=
1
⌊
m
d
⌋
1
=\sum_{d=1}^n\varphi(d)\sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{m}{d} \rfloor}1
=d=1∑nφ(d)i=1∑⌊dn⌋j=1∑⌊dm⌋1
=
∑
d
=
1
n
φ
(
d
)
⌊
n
d
⌋
⌊
m
d
⌋
=\sum_{d=1}^n\varphi(d)\lfloor \frac{n}{d} \rfloor\lfloor \frac{m}{d} \rfloor
=d=1∑nφ(d)⌊dn⌋⌊dm⌋
预处理欧拉函数前缀和,再套上整除分块即可
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL N = 1e5+7;
LL phi[N];
LL v[N],prime[N],tot=0;
void init(LL n)
{
phi[1]=1;
for(LL i=2;i<=n;i++)
{
if(!v[i])
{
v[i]=i;
prime[++tot]=i;
phi[i]=i-1;
}
for(LL j=1;j<=tot;j++)
{
if(v[i]<prime[j]||i*prime[j]>n) break;
v[i*prime[j]]=prime[j];
if(v[i]%prime[j]==0)
{
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
else phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
for(LL i=1;i<=n;i++)
phi[i]=phi[i]+phi[i-1];
}
int main()
{
freopen("energy.in","r",stdin);
freopen("energy.out","w",stdout);
init(1e5);
LL n,m;
cin>>n>>m;
if(n>m) swap(n,m);
LL ans=0;
LL l=1,r;
for(;l<=n;l=r+1)
{
r=min((n/(n/l)),(m/(m/l)));
ans=(ans+1ll*(phi[r]-phi[l-1])*1ll*(n/l)*(m/l));
}
cout<<2*ans-n*m;
return 0;
}
YY的GCD
求
∑
i
=
1
n
∑
j
=
1
m
[
g
c
d
(
i
,
j
)
∈
p
r
i
m
e
]
\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)\in prime]
i=1∑nj=1∑m[gcd(i,j)∈prime]
化简:
∑
i
=
1
n
∑
j
=
1
m
[
g
c
d
(
i
,
j
)
∈
p
r
i
m
e
]
\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)\in prime]
i=1∑nj=1∑m[gcd(i,j)∈prime]
=
∑
i
=
1
n
∑
j
=
1
m
∑
d
∣
i
,
d
∣
j
[
g
c
d
(
i
,
j
)
=
=
d
]
,
d
∈
p
r
i
m
e
=\sum_{i=1}^n\sum_{j=1}^m\sum_{d|i,d|j}[gcd(i,j)==d],d\in prime
=i=1∑nj=1∑md∣i,d∣j∑[gcd(i,j)==d],d∈prime
=
∑
d
=
1
n
∑
d
∣
i
n
∑
d
∣
j
m
[
g
c
d
(
i
,
j
)
=
=
d
]
,
d
∈
p
r
i
m
e
=\sum_{d=1}^n\sum_{d|i}^n\sum_{d|j}^m[gcd(i,j)==d],d\in prime
=d=1∑nd∣i∑nd∣j∑m[gcd(i,j)==d],d∈prime
=
∑
d
=
1
n
∑
i
=
1
⌊
n
d
⌋
∑
j
=
1
⌊
m
d
⌋
[
g
c
d
(
i
,
j
)
=
=
1
]
,
d
∈
p
r
i
m
e
=\sum_{d=1}^n\sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{m}{d} \rfloor}[gcd(i,j)==1],d\in prime
=d=1∑ni=1∑⌊dn⌋j=1∑⌊dm⌋[gcd(i,j)==1],d∈prime
=
∑
d
=
1
n
∑
i
=
1
⌊
n
d
⌋
∑
j
=
1
⌊
m
d
⌋
∑
k
∣
i
,
k
∣
j
μ
(
k
)
,
d
∈
p
r
i
m
e
=\sum_{d=1}^n\sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{m}{d} \rfloor}\sum_{k|i,k|j}\mu(k),d\in prime
=d=1∑ni=1∑⌊dn⌋j=1∑⌊dm⌋k∣i,k∣j∑μ(k),d∈prime
=
∑
d
=
1
n
∑
k
=
1
n
μ
(
k
)
∑
i
=
1
⌊
n
d
k
⌋
∑
j
=
1
⌊
m
d
k
⌋
1
,
d
∈
p
r
i
m
e
=\sum_{d=1}^n\sum_{k=1}^n\mu(k)\sum_{i=1}^{\lfloor \frac{n}{dk} \rfloor}\sum_{j=1}^{\lfloor \frac{m}{dk} \rfloor}1,d\in prime
=d=1∑nk=1∑nμ(k)i=1∑⌊dkn⌋j=1∑⌊dkm⌋1,d∈prime
=
∑
d
=
1
n
∑
k
=
1
n
μ
(
k
)
⌊
n
d
k
⌋
⌊
m
d
k
⌋
,
d
∈
p
r
i
m
e
=\sum_{d=1}^n\sum_{k=1}^n\mu(k)\lfloor \frac{n}{dk} \rfloor\lfloor \frac{m}{dk} \rfloor,d\in prime
=d=1∑nk=1∑nμ(k)⌊dkn⌋⌊dkm⌋,d∈prime
=
∑
T
=
1
n
⌊
n
T
⌋
⌊
m
T
⌋
∑
d
∣
T
μ
(
T
d
)
,
d
∈
p
r
i
m
e
=\sum_{T=1}^n\lfloor \frac{n}{T} \rfloor\lfloor \frac{m}{T} \rfloor\sum_{d|T}\mu(\frac{T}{d}),d\in prime
=T=1∑n⌊Tn⌋⌊Tm⌋d∣T∑μ(dT),d∈prime
设
f
(
n
)
=
∑
d
∣
n
,
d
∈
p
r
i
m
e
μ
(
T
d
)
f(n)=\sum_{d|n,d\in prime }\mu(\frac{T}{d})
f(n)=∑d∣n,d∈primeμ(dT)
a
n
s
=
∑
T
=
1
n
⌊
n
T
⌋
⌊
m
T
⌋
f
(
T
)
ans=\sum_{T=1}^n\lfloor \frac{n}{T} \rfloor\lfloor \frac{m}{T} \rfloor f(T)
ans=T=1∑n⌊Tn⌋⌊Tm⌋f(T)
预处理
f
(
n
)
f(n)
f(n)的前缀和,这个可以枚举质数
d
d
d和
d
d
d的倍数
n
n
n算出,因为只枚举质数,所以复杂度
O
(
n
l
o
g
n
l
o
g
n
)
O(n\;logn\;logn)
O(nlognlogn)
接着整除分块即可
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e7+7;
int u[N];
int prime[N],top=0;
LL T[N];
LL sum[N];
bool vis[N];
void sieve(int n)
{
u[1]=1;
for(int i=2;i<=n;i++)
{
if(!vis[i])
{
u[i]=-1;
prime[++top]=i;
}
for(int j=1;j<=top&&i*prime[j]<=n;j++)
{
vis[i*prime[j]]=1;
if(i%prime[j]==0)
{
u[i*prime[j]]=0;
break;
}
else u[i*prime[j]]=u[i]*u[prime[j]];
}
}
for(int j=1;j<=top;j++)
{
for(int i=1;i*prime[j]<=n;i++)
{
T[i*prime[j]]+=u[i];
}
}
for(int i=1;i<=n;i++)
sum[i]=sum[i-1]+T[i];
}
LL count(int n,int m)
{
LL res=0;
for(int l=1,r=0;l<=n;l=r+1)
{
r=min(n/(n/l),m/(m/l));
res=res+(sum[r]-sum[l-1])*(n/l)*(m/l);
}
return res;
}
int main()
{
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
int T;
cin>>T;
sieve(1e7);
while(T--)
{
int n,m;
scanf("%d%d",&n,&m);
if(n>m) swap(n,m);
printf("%lld\n",count(n,m));
}
return 0;
}
[SDOI2015] 约数个数和
求
∑
i
=
1
n
∑
j
=
1
m
d
(
i
j
)
\sum_{i=1}^n\sum_{j=1}^md(ij)
i=1∑nj=1∑md(ij)
其中
d
(
n
)
d(n)
d(n)表示
n
n
n的约数个数和
首先有引理
d
(
i
j
)
=
∑
x
∣
i
∑
y
∣
j
[
g
c
d
(
x
,
y
)
=
=
1
]
d(ij)=\sum_{x|i}\sum_{y|j}[gcd(x,y)==1]
d(ij)=x∣i∑y∣j∑[gcd(x,y)==1]
证明详见这篇blog
根据引理,所求即为
∑
i
=
1
n
∑
j
=
1
m
∑
x
∣
i
∑
y
∣
j
[
g
c
d
(
x
,
y
)
=
=
1
]
\sum_{i=1}^n\sum_{j=1}^m\sum_{x|i}\sum_{y|j}[gcd(x,y)==1]
i=1∑nj=1∑mx∣i∑y∣j∑[gcd(x,y)==1]
=
∑
x
=
1
n
∑
y
=
1
m
[
g
c
d
(
x
,
y
)
=
=
1
]
∑
x
∣
i
∑
y
∣
j
1
=\sum_{x=1}^n\sum_{y=1}^m[gcd(x,y)==1]\sum_{x|i}\sum_{y|j}1
=x=1∑ny=1∑m[gcd(x,y)==1]x∣i∑y∣j∑1
=
∑
x
=
1
n
∑
y
=
1
m
[
g
c
d
(
x
,
y
)
=
=
1
]
∑
i
=
1
⌊
n
x
⌋
∑
j
=
1
⌊
m
y
⌋
1
=\sum_{x=1}^n\sum_{y=1}^m[gcd(x,y)==1]\sum_{i=1}^{\lfloor \frac{n}{x} \rfloor}\sum_{j=1}^{\lfloor \frac{m}{y} \rfloor}1
=x=1∑ny=1∑m[gcd(x,y)==1]i=1∑⌊xn⌋j=1∑⌊ym⌋1
=
∑
x
=
1
n
∑
y
=
1
m
[
g
c
d
(
x
,
y
)
=
=
1
]
⌊
n
x
⌋
⌊
m
y
⌋
=\sum_{x=1}^n\sum_{y=1}^m[gcd(x,y)==1]\lfloor \frac{n}{x} \rfloor\lfloor \frac{m}{y} \rfloor
=x=1∑ny=1∑m[gcd(x,y)==1]⌊xn⌋⌊ym⌋
=
∑
x
=
1
n
∑
y
=
1
m
∑
d
∣
x
,
d
∣
y
μ
(
d
)
⌊
n
x
⌋
⌊
m
y
⌋
=\sum_{x=1}^n\sum_{y=1}^m\sum_{d|x,d|y}\mu(d)\lfloor \frac{n}{x} \rfloor\lfloor \frac{m}{y} \rfloor
=x=1∑ny=1∑md∣x,d∣y∑μ(d)⌊xn⌋⌊ym⌋
=
∑
d
=
1
n
μ
(
d
)
∑
d
∣
x
n
∑
d
∣
y
m
⌊
n
x
⌋
⌊
m
y
⌋
=\sum_{d=1}^n\mu(d)\sum_{d|x}^n\sum_{d|y}^m\lfloor \frac{n}{x} \rfloor\lfloor \frac{m}{y} \rfloor
=d=1∑nμ(d)d∣x∑nd∣y∑m⌊xn⌋⌊ym⌋
=
∑
d
=
1
n
μ
(
d
)
∑
x
=
1
⌊
n
d
⌋
∑
y
=
1
⌊
m
d
⌋
⌊
n
d
x
⌋
⌊
m
d
y
⌋
=\sum_{d=1}^n\mu(d)\sum_{x=1}^{\lfloor \frac{n}{d} \rfloor}\sum_{y=1}^{\lfloor \frac{m}{d} \rfloor}\lfloor \frac{n}{dx} \rfloor\lfloor \frac{m}{dy} \rfloor
=d=1∑nμ(d)x=1∑⌊dn⌋y=1∑⌊dm⌋⌊dxn⌋⌊dym⌋
=
∑
d
=
1
n
μ
(
d
)
∑
x
=
1
⌊
n
d
⌋
⌊
n
d
x
⌋
∑
y
=
1
⌊
m
d
⌋
⌊
m
d
y
⌋
=\sum_{d=1}^n\mu(d)\sum_{x=1}^{\lfloor \frac{n}{d} \rfloor}\lfloor \frac{n}{dx} \rfloor \sum_{y=1}^{\lfloor \frac{m}{d} \rfloor}\lfloor \frac{m}{dy} \rfloor
=d=1∑nμ(d)x=1∑⌊dn⌋⌊dxn⌋y=1∑⌊dm⌋⌊dym⌋
设
f
(
n
)
=
∑
i
=
1
n
⌊
n
i
⌋
f(n)=\sum_{i=1}^n\lfloor \frac{n}{i}\rfloor
f(n)=∑i=1n⌊in⌋,
N
=
⌊
n
d
⌋
,
M
=
⌊
m
d
⌋
N=\lfloor \frac{n}{d} \rfloor,M=\lfloor \frac{m}{d} \rfloor
N=⌊dn⌋,M=⌊dm⌋
=
∑
d
=
1
n
μ
(
d
)
∑
x
=
1
N
⌊
N
x
⌋
∑
y
=
1
M
⌊
M
y
⌋
=\sum_{d=1}^n\mu(d)\sum_{x=1}^{N}\lfloor \frac{N}{x} \rfloor \sum_{y=1}^{M}\lfloor \frac{M}{y} \rfloor
=d=1∑nμ(d)x=1∑N⌊xN⌋y=1∑M⌊yM⌋
=
∑
d
=
1
n
μ
(
d
)
f
(
N
)
f
(
M
)
=\sum_{d=1}^n\mu(d)f(N)f(M)
=d=1∑nμ(d)f(N)f(M)
=
∑
d
=
1
n
μ
(
d
)
f
(
⌊
n
d
)
f
(
⌊
m
d
⌋
)
=\sum_{d=1}^n\mu(d)f(\lfloor \frac{n}{d})f(\lfloor \frac{m}{d} \rfloor)
=d=1∑nμ(d)f(⌊dn)f(⌊dm⌋)
这个形式就可以很舒服的整除分块了
f
(
n
)
f(n)
f(n)可以整除分块
O
(
n
n
)
O(n\sqrt n)
O(nn)预处理
总复杂度
O
(
n
n
+
T
n
)
O(n\sqrt n+T\sqrt n)
O(nn+Tn),
T
T
T是询问次数
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 5e4+100;
inline int read()
{
int X=0; bool flag=1; char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}
while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}
if(flag) return X;
return ~(X-1);
}
LL prime[N],tot,u[N],sum[N],f[N];
bool vis[N];
void prework(int n)
{
u[1]=1;
for(int i=2;i<=n;i++)
{
if(!vis[i])
{
prime[++tot]=i;
u[i]=-1;
}
for(int j=1;j<=tot&&prime[j]*i<=n;j++)
{
int p=prime[j];
vis[i*p]=1;
if(i%p==0) break;
else u[i*p]=u[i]*u[p];
}
}
for(int i=1;i<=n;i++)
sum[i]=sum[i-1]+u[i];
for(int i=1;i<=n;i++)
{
for(int l=1,r;l<=i;l=r+1)
{
r=(i/(i/l));
f[i]=f[i]+1ll*(r-l+1)*1ll*(i/l);
}
}
}
int main()
{
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
int t,n,m;
cin>>t;
prework(50000);
while(t--)
{
n=read();
m=read();
LL range=min(n,m);
LL ans=0;
for(int l=1,r;l<=range;l=r+1)
{
r=min(n/(n/l),m/(m/l));
ans=ans+(sum[r]-sum[l-1])*1ll*f[n/l]*1ll*f[m/l];
}
printf("%lld\n",ans);
}
return 0;
}
[HAOI2011]Problem b
求
∑
l
≤
i
≤
r
∑
a
≤
j
≤
b
[
g
c
d
(
i
,
j
)
=
=
k
]
\sum_{l\leq i \leq r}\sum_{a\leq j\leq b}[gcd(i,j)==k]
∑l≤i≤r∑a≤j≤b[gcd(i,j)==k]
观察到这类似于二维前缀和,我们只需要求出这样一个式子就行了
∑
i
=
1
n
∑
j
=
1
m
[
g
c
d
(
i
,
j
)
=
=
k
]
\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)==k]
i=1∑nj=1∑m[gcd(i,j)==k]
令
N
=
⌊
n
k
⌋
N=\lfloor \frac{n}{k} \rfloor
N=⌊kn⌋,
M
=
⌊
m
k
⌋
M=\lfloor \frac{m}{k} \rfloor
M=⌊km⌋
=
∑
i
=
1
N
∑
j
=
1
M
[
g
c
d
(
i
,
j
)
=
=
1
]
=\sum_{i=1}^{N}\sum_{j=1}^{M}[gcd(i,j)==1]
=i=1∑Nj=1∑M[gcd(i,j)==1]
=
∑
i
=
1
N
∑
j
=
1
M
∑
d
∣
i
,
d
∣
j
μ
(
d
)
=\sum_{i=1}^{N}\sum_{j=1}^{M}\sum_{d|i,d|j}\mu(d)
=i=1∑Nj=1∑Md∣i,d∣j∑μ(d)
=
∑
d
=
1
N
μ
(
d
)
∑
d
∣
i
N
∑
d
∣
j
M
1
=\sum_{d=1}^N\mu(d) \sum_{d|i}^{N}\sum_{d|j}^{M}1
=d=1∑Nμ(d)d∣i∑Nd∣j∑M1
=
∑
d
=
1
N
μ
(
d
)
∑
i
=
1
⌊
N
d
⌋
∑
j
=
1
⌊
M
d
⌋
1
=\sum_{d=1}^N\mu(d) \sum_{i=1}^{\lfloor \frac{N}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{M}{d} \rfloor}1
=d=1∑Nμ(d)i=1∑⌊dN⌋j=1∑⌊dM⌋1
=
∑
d
=
1
N
μ
(
d
)
⌊
N
d
⌋
⌊
M
d
⌋
=\sum_{d=1}^N\mu(d)\lfloor \frac{N}{d} \rfloor\lfloor \frac{M}{d} \rfloor
=d=1∑Nμ(d)⌊dN⌋⌊dM⌋
直接整除分块即可
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+7;
int u[N],vis[N];
int prime[N],top=0;
int sum[N];
void sieve(int n)
{
u[1]=1;
for(int i=2;i<=n;i++)
{
if(vis[i]==0)
{
prime[++top]=i;
u[i]=-1;
}
for(int j=1;j<=top&&prime[j]*i<=n;j++)
{
vis[i*prime[j]]=1;
if(i%prime[j]==0)
{
u[i*prime[j]]=0;
break;
}
else u[i*prime[j]]=u[i]*u[prime[j]];
}
}
for(int i=1;i<=n;i++)
sum[i]=sum[i-1]+u[i];
}
int count(int a,int b,int d)
{
a/=d;
b/=d;
int res=0;
if(a>b) swap(a,b);
for(int L=1,R=0;L<=a;L=R+1)
{
R=min(a/(a/L),b/(b/L));
res=res+(sum[R]-sum[L-1])*(a/L)*(b/L);
}
return res;
}
int main()
{
sieve(1e5+7);
int T;
cin>>T;
while(T--)
{
int a,b,c,d,k;
scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
printf("%d\n",count(b,d,k)-count(b,c-1,k)-count(a-1,d,k)+count(a-1,c-1,k));
}
return 0;
}
BZOJ4407 于神之怒加强版
求
∑
i
=
1
n
∑
j
=
1
m
gcd
(
i
,
j
)
k
m
o
d
1
0
9
+
7
\sum_{i=1}^n\sum_{j=1}^m\gcd(i,j)^k\ \bmod 10^9+7
i=1∑nj=1∑mgcd(i,j)k mod109+7
化简
∑
i
=
1
n
∑
j
=
1
m
gcd
(
i
,
j
)
k
\sum_{i=1}^n\sum_{j=1}^m\gcd(i,j)^k
i=1∑nj=1∑mgcd(i,j)k
=
∑
i
=
1
n
∑
j
=
1
m
∑
d
∣
i
,
d
∣
j
[
g
c
d
(
i
,
j
)
=
=
d
]
d
k
=\sum_{i=1}^n\sum_{j=1}^m\sum_{d|i,d|j}[gcd(i,j)==d]d^k
=i=1∑nj=1∑md∣i,d∣j∑[gcd(i,j)==d]dk
=
∑
d
=
1
n
d
k
∑
i
=
1
n
∑
j
=
1
m
[
g
c
d
(
i
,
j
)
=
=
d
]
=\sum_{d=1}^n d^k \sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)==d]
=d=1∑ndki=1∑nj=1∑m[gcd(i,j)==d]
=
∑
d
=
1
n
d
k
∑
i
=
1
⌊
n
d
⌋
∑
j
=
1
⌊
m
d
⌋
[
g
c
d
(
i
,
j
)
=
=
1
]
=\sum_{d=1}^n d^k \sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{m}{d} \rfloor}[gcd(i,j)==1]
=d=1∑ndki=1∑⌊dn⌋j=1∑⌊dm⌋[gcd(i,j)==1]
=
∑
d
=
1
n
d
k
∑
i
=
1
⌊
n
d
⌋
∑
j
=
1
⌊
m
d
⌋
∑
k
∣
i
,
k
∣
j
μ
(
k
)
=\sum_{d=1}^n d^k \sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{m}{d} \rfloor}\sum_{k|i,k|j}\mu(k)
=d=1∑ndki=1∑⌊dn⌋j=1∑⌊dm⌋k∣i,k∣j∑μ(k)
=
∑
d
=
1
n
d
k
∑
k
=
1
⌊
n
d
⌋
μ
(
k
)
∑
k
∣
i
⌊
n
d
⌋
∑
k
∣
j
⌊
m
d
⌋
1
=\sum_{d=1}^n d^k\sum_{k=1}^{\lfloor \frac{n}{d} \rfloor}\mu(k) \sum_{k|i}^{\lfloor \frac{n}{d} \rfloor}\sum_{k|j}^{\lfloor \frac{m}{d} \rfloor}1
=d=1∑ndkk=1∑⌊dn⌋μ(k)k∣i∑⌊dn⌋k∣j∑⌊dm⌋1
=
∑
d
=
1
n
d
k
∑
k
=
1
⌊
n
d
⌋
μ
(
k
)
∑
i
=
1
⌊
n
d
k
⌋
∑
j
=
1
⌊
m
d
k
⌋
1
=\sum_{d=1}^n d^k\sum_{k=1}^{\lfloor \frac{n}{d} \rfloor}\mu(k) \sum_{i=1}^{\lfloor \frac{n}{dk} \rfloor}\sum_{j=1}^{\lfloor \frac{m}{dk} \rfloor}1
=d=1∑ndkk=1∑⌊dn⌋μ(k)i=1∑⌊dkn⌋j=1∑⌊dkm⌋1
=
∑
d
=
1
n
d
k
∑
k
=
1
⌊
n
d
⌋
μ
(
k
)
⌊
n
d
k
⌋
⌊
m
d
k
⌋
=\sum_{d=1}^n d^k\sum_{k=1}^{\lfloor \frac{n}{d} \rfloor}\mu(k) \lfloor \frac{n}{dk} \rfloor\lfloor \frac{m}{dk} \rfloor
=d=1∑ndkk=1∑⌊dn⌋μ(k)⌊dkn⌋⌊dkm⌋
=
∑
T
=
1
n
⌊
n
T
⌋
⌊
m
T
⌋
∑
d
∣
T
n
d
k
μ
(
n
d
)
=\sum_{T=1}^n\lfloor \frac{n}{T} \rfloor\lfloor \frac{m}{T} \rfloor\sum_{d|T}^n d^k \mu({ \frac{n}{d} })
=T=1∑n⌊Tn⌋⌊Tm⌋d∣T∑ndkμ(dn)
注意因为枚举了倍数,所以k前的
∑
\sum
∑就被提前了,不能算
设
f
(
n
)
=
∑
d
∣
n
d
k
μ
(
n
d
)
f(n)=\sum_{d|n}d^k\mu(\frac{n}{d})
f(n)=d∣n∑dkμ(dn)
那么
f
(
n
)
f(n)
f(n)是两个积性函数的狄利克雷卷积,所以
f
(
n
)
f(n)
f(n)是积性函数
直接线性筛晒一下就行了
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N =5e6+7;
const int mod = 1e9+7;
LL Pow(LL a,LL b)
{
LL res=1;
while(b)
{
if(b&1) res=1ll*res*a%mod;
a=1ll*a*a%mod;
b>>=1;
}
return res;
}
int v[N],prime[N],tot=0;
LL mu[N],pk[N],f[N];
int k;
void init(int n)
{
mu[1]=1;
f[1]=1;
for(int i=2;i<=n;i++)
{
if(!v[i])
{
v[i]=i;
prime[++tot]=i;
pk[i]=Pow(i,k);
f[i]=(pk[i]-1+mod)%mod;
}
for(int j=1;j<=tot;j++)
{
if(prime[j]>v[i]||i*prime[j]>n) break;
v[i*prime[j]]=prime[j];
if(i%prime[j]==0)
{
f[i*prime[j]]=1ll*f[i]*pk[prime[j]]%mod;
break;
}
else f[i*prime[j]]=1ll*f[i]*f[prime[j]];
}
}
for(int i=1;i<=n;i++)
f[i]=(f[i]+f[i-1])%mod;
}
int main()
{
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
int T;
cin>>T>>k;
init(5e6);
while(T--)
{
int n,m;
scanf("%d %d",&n,&m);
if(n>m) swap(n,m);
LL ans=0;
int l=1,r;
for(;l<=n;l=r+1)
{
r=min(n/(n/l),m/(m/l));
ans=(ans+(f[r]-f[l-1]+mod)%mod*(n/l)%mod*(m/l)%mod)%mod;
}
printf("%lld\n",ans);
}
return 0;
}
技巧总结
1:可以枚举要求的数,比如gcd,然后用布尔表达式写出来
2:将某些项提前,然后将和它相关的项用改成枚举倍数,使上指标方便进行整除分块
3:一般情况最终有两种情况:
一是可以直接写成整除分块的形式
二是整除下有两个字母的乘积,此时可以枚举乘积,并将乘积提前,此时其余的项是封闭的,且一般可以写成一个关于乘积的函数,可以用线性筛预处理出