题目:BZOJ3529.
题目大意:设
f
(
i
,
j
)
=
∑
d
∣
g
c
d
(
i
,
j
)
d
f(i,j)=\sum_{d|gcd(i,j)}d
f(i,j)=∑d∣gcd(i,j)d,给定
Q
Q
Q组询问,每次询问
n
,
m
,
a
n,m,a
n,m,a,求
∑
i
=
1
n
∑
j
=
1
,
f
(
i
,
j
)
≤
a
m
f
(
i
,
j
)
\sum_{i=1}^{n}\sum_{j=1,f(i,j)\leq a}^{m}f(i,j)
∑i=1n∑j=1,f(i,j)≤amf(i,j).
1
≤
n
,
m
≤
1
0
5
,
1
≤
q
≤
2
∗
1
0
4
,
1
≤
∣
a
∣
≤
1
0
9
1\leq n,m\leq 10^5,1\leq q\leq 2*10^4,1\leq |a|\leq 10^9
1≤n,m≤105,1≤q≤2∗104,1≤∣a∣≤109.
先考虑没有
a
a
a限制的情况,那么:
∑
i
=
1
n
∑
j
=
1
m
f
(
i
,
j
)
=
∑
i
=
1
n
∑
j
=
1
m
∑
d
∣
g
c
d
(
i
,
j
)
d
=
∑
d
=
1
m
i
n
(
n
,
m
)
(
∑
t
∣
d
t
)
(
∑
i
=
1
n
∑
j
=
1
m
[
g
c
d
(
i
,
j
)
=
d
]
)
\sum_{i=1}^{n}\sum_{j=1}^{m}f(i,j)\\ =\sum_{i=1}^{n}\sum_{j=1}^{m}\sum_{d|gcd(i,j)}d\\ =\sum_{d=1}^{min(n,m)}(\sum_{t|d}t)(\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)=d])
i=1∑nj=1∑mf(i,j)=i=1∑nj=1∑md∣gcd(i,j)∑d=d=1∑min(n,m)(t∣d∑t)(i=1∑nj=1∑m[gcd(i,j)=d])
设
σ
(
n
)
=
∑
d
∣
n
d
\sigma(n)=\sum_{d|n}d
σ(n)=∑d∣nd,那么:
∑
d
=
1
m
i
n
(
n
,
m
)
(
∑
t
∣
d
t
)
(
∑
i
=
1
n
∑
j
=
1
m
[
g
c
d
(
i
,
j
)
=
d
]
)
=
∑
d
=
1
m
i
n
(
n
,
m
)
σ
(
d
)
∑
i
=
1
n
∑
j
=
1
m
[
g
c
d
(
i
,
j
)
=
d
]
=
∑
d
=
1
m
i
n
(
n
,
m
)
σ
(
d
)
∑
i
=
1
⌊
n
d
⌋
∑
j
=
1
⌊
m
d
⌋
[
g
c
d
(
i
,
j
)
=
1
]
=
∑
d
=
1
m
i
n
(
n
,
m
)
σ
(
d
)
∑
i
=
1
⌊
n
d
⌋
∑
j
=
1
⌊
m
d
⌋
∑
t
∣
i
∧
t
∣
j
μ
(
t
)
=
∑
d
=
1
m
i
n
(
n
,
m
)
σ
(
d
)
∑
t
=
1
⌊
m
i
n
(
n
,
m
)
d
⌋
μ
(
t
)
⌊
n
d
t
⌋
⌊
m
d
t
⌋
\sum_{d=1}^{min(n,m)}(\sum_{t|d}t)(\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)=d])\\ =\sum_{d=1}^{min(n,m)}\sigma(d)\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)=d]\\ =\sum_{d=1}^{min(n,m)}\sigma(d)\sum_{i=1}^{\left\lfloor\frac{n}{d}\right\rfloor}\sum_{j=1}^{\left\lfloor\frac{m}{d}\right\rfloor}[gcd(i,j)=1]\\ =\sum_{d=1}^{min(n,m)}\sigma(d)\sum_{i=1}^{\left\lfloor\frac{n}{d}\right\rfloor}\sum_{j=1}^{\left\lfloor\frac{m}{d}\right\rfloor}\sum_{t|i\wedge t|j}\mu(t)\\ =\sum_{d=1}^{min(n,m)}\sigma(d)\sum_{t=1}^{\left\lfloor\frac{min(n,m)}{d}\right\rfloor}\mu(t)\left\lfloor\frac{n}{dt}\right\rfloor\left\lfloor\frac{m}{dt}\right\rfloor
d=1∑min(n,m)(t∣d∑t)(i=1∑nj=1∑m[gcd(i,j)=d])=d=1∑min(n,m)σ(d)i=1∑nj=1∑m[gcd(i,j)=d]=d=1∑min(n,m)σ(d)i=1∑⌊dn⌋j=1∑⌊dm⌋[gcd(i,j)=1]=d=1∑min(n,m)σ(d)i=1∑⌊dn⌋j=1∑⌊dm⌋t∣i∧t∣j∑μ(t)=d=1∑min(n,m)σ(d)t=1∑⌊dmin(n,m)⌋μ(t)⌊dtn⌋⌊dtm⌋
考虑枚举
c
=
d
t
c=dt
c=dt,那么:
=
∑
d
=
1
m
i
n
(
n
,
m
)
σ
(
d
)
∑
t
=
1
⌊
m
i
n
(
n
,
m
)
d
⌋
μ
(
t
)
⌊
n
d
t
⌋
⌊
m
d
t
⌋
=
∑
c
=
1
m
i
n
(
n
,
m
)
⌊
n
c
⌋
⌊
m
c
⌋
∑
d
∣
c
μ
(
c
d
)
σ
(
d
)
=\sum_{d=1}^{min(n,m)}\sigma(d)\sum_{t=1}^{\left\lfloor\frac{min(n,m)}{d}\right\rfloor}\mu(t)\left\lfloor\frac{n}{dt}\right\rfloor\left\lfloor\frac{m}{dt}\right\rfloor\\ =\sum_{c=1}^{min(n,m)}\left\lfloor\frac{n}{c}\right\rfloor\left\lfloor\frac{m}{c}\right\rfloor\sum_{d|c}\mu(\frac{c}{d})\sigma(d)
=d=1∑min(n,m)σ(d)t=1∑⌊dmin(n,m)⌋μ(t)⌊dtn⌋⌊dtm⌋=c=1∑min(n,m)⌊cn⌋⌊cm⌋d∣c∑μ(dc)σ(d)
线性筛出 μ \mu μ和 σ \sigma σ并预处理出它们的dirichlet卷积的前缀和 g g g,然后除法分块处理即可做到 O ( n ) O(\sqrt{n}) O(n)处理一次询问.
考虑离线处理 a a a的限制.我们先对询问按照 a a a排序,把所有 d d d按照 σ ( d ) \sigma(d) σ(d)大小排序,并用树状数组动态维护 g g g,即可做到 O ( n log 2 n + Q n log n ) O(n\log^2n+Q\sqrt{n}\log n) O(nlog2n+Qnlogn).
具体来说,每次当我们要加入一个数 d d d的贡献时,我们枚举 d d d的倍数,把这些倍数加上 d d d的贡献.查询时用树状数组维护前缀和即可.
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define Abigail inline void
typedef long long LL;
const int N=100000,Q=20000;
const LL mod=(1LL<<31)-1;
int tp,pr[N+9],b[N+9];
LL mu[N+9],sigma[N+9],sd[N+9];
void sieve(int n){ //先把约数和函数筛错,重写一遍后再把Mobius函数筛错的我是不是没了...
for (int i=2;i<=n;++i) b[i]=1;
sigma[1]=mu[1]=1;int v;
for (int i=2;i<=n;++i){
if (b[i]) pr[++tp]=i,mu[i]=-1,sigma[i]=sd[i]=i+1;
for (int j=1;j<=tp&&i*pr[j]<=n;++j){
b[v=i*pr[j]]=0;
if (i%pr[j]==0){
mu[v]=0;
sd[v]=sd[i]*pr[j]+1;sigma[v]=sigma[i]/sd[i]*sd[v];
break;
}
mu[v]=-mu[i];
sd[v]=pr[j]+1;sigma[v]=sigma[i]*sigma[pr[j]];
}
}
}
int t;
struct Question{
int n,m,id;
LL a;
}q[Q+9];
LL ans[Q+9];
bool cmp1(const Question &a,const Question &b){return a.a<b.a;}
int d[N+9];
bool cmp2(const int &a,const int &b){return sigma[a]<sigma[b];}
LL g[N+9];
void Bit_add(int x,LL v){for (;x<=N;x+=x&-x) g[x]+=v;}
LL Bit_query(int x){LL sum=0;for (;x;x-=x&-x) sum+=g[x];return sum;}
LL Bit_query(int x,int y){return Bit_query(y)-Bit_query(x-1);}
void solve_add(int x){
for (int i=1;i*x<=N;++i)
Bit_add(i*x,sigma[x]*mu[i]);
}
LL solve_query(int n,int m){
LL ans=0;
if (n>m) swap(n,m);
for (int l=1,r;l<=n;l=r+1){
r=min(n/(n/l),m/(m/l));
ans+=(n/l)*(m/l)*Bit_query(l,r);
}
return ans;
}
Abigail into(){
scanf("%d",&t);
for (int i=1;i<=t;++i){
scanf("%d%d%lld",&q[i].n,&q[i].m,&q[i].a);
q[i].id=i;
}
}
Abigail work(){
sieve(N);
sort(q+1,q+1+t,cmp1);
for (int i=1;i<=N;++i) d[i]=i;
sort(d+1,d+1+N,cmp2);
int now=0;
for (int i=1;i<=t;++i){
while (now<N&&sigma[d[now+1]]<=q[i].a) solve_add(d[++now]);
ans[q[i].id]=solve_query(q[i].n,q[i].m);
}
}
Abigail outo(){
for (int i=1;i<=t;++i)
printf("%lld\n",ans[i]&mod);
}
int main(){
into();
work();
outo();
return 0;
}