概述
正题
题目链接:http://www.ybtoj.com.cn/contest/122/problem/3
题目大意
S
(
i
)
S(i)
S(i)表示
i
i
i的约数个数,
Q
Q
Q次询问给出
n
,
m
n,m
n,m求
∑
a
=
1
n
∑
b
=
1
m
S
(
a
2
)
×
S
(
b
2
)
×
S
(
a
×
b
)
sum_{a=1}^nsum_{b=1}^mS(a^2)times S(b^2)times S(atimes b)
a=1∑nb=1∑mS(a2)×S(b2)×S(a×b)
1 ≤ Q ≤ 1 0 4 , 1 ≤ n , m ≤ 2 × 1 0 5 1leq Qleq 10^4,1leq n,mleq 2times 10^5 1≤Q≤104,1≤n,m≤2×105
解题思路
前面的推式子挺套路的
首先我们要搞定
S
(
n
2
)
S(n^2)
S(n2)这个东西,一个经典的结论就是
S
(
n
×
m
)
=
∑
i
∣
n
∑
j
∣
m
[
g
c
d
(
i
,
j
)
=
1
]
S(ntimes m)=sum_{i|n}sum_{j|m}[gcd(i,j)=1]
S(n×m)=∑i∣n∑j∣m[gcd(i,j)=1]。莫反一下就有
S
(
a
×
b
)
=
∑
d
∣
(
a
×
b
)
μ
(
d
)
∑
i
×
d
∣
a
∑
j
×
d
∣
b
1
S(atimes b)=sum_{d|(atimes b)}mu(d)sum_{itimes d|a}sum_{jtimes d|b}1
S(a×b)=d∣(a×b)∑μ(d)i×d∣a∑j×d∣b∑1
所以就有
S
(
n
2
)
=
∑
d
∣
n
μ
(
d
)
S
(
n
d
)
2
S(n^2)=sum_{d|n}mu(d)S(frac{n}{d})^2
S(n2)=d∣n∑μ(d)S(dn)2
用线性筛筛出前面的
S
S
S,然后
O
(
n
log
n
)
O(nlog n)
O(nlogn)求出
h
(
n
)
=
S
(
n
2
)
h(n)=S(n^2)
h(n)=S(n2)
然后化一下式子
∑
a
=
1
n
∑
b
=
1
m
h
(
a
)
×
h
(
b
)
∑
i
∣
a
∑
j
∣
b
[
g
c
d
(
i
,
j
)
=
1
]
sum_{a=1}^nsum_{b=1}^mh(a)times h(b)sum_{i|a}sum_{j|b}[gcd(i,j)=1]
a=1∑nb=1∑mh(a)×h(b)i∣a∑j∣b∑[gcd(i,j)=1]
∑
d
=
1
μ
(
d
)
(
∑
d
∣
i
∑
i
∣
a
h
(
a
)
)
(
∑
d
∣
j
∑
j
∣
b
h
(
b
)
)
sum_{d=1}mu(d)(sum_{d|i}sum_{i|a}h(a))(sum_{d|j}sum_{j|b}h(b))
d=1∑μ(d)(d∣i∑i∣a∑h(a))(d∣j∑j∣b∑h(b))
∑
d
=
1
μ
(
d
)
(
∑
d
∣
a
S
(
a
d
)
h
(
a
)
)
(
∑
d
∣
b
S
(
b
d
)
h
(
b
)
)
sum_{d=1}mu(d)(sum_{d|a}S(frac{a}{d})h(a))(sum_{d|b}S(frac{b}{d})h(b))
d=1∑μ(d)(d∣a∑S(da)h(a))(d∣b∑S(db)h(b))
然后就好像没得化简了,先处理出 F ( d , n ) = ∑ i = 1 n h ( i × d ) S ( i ) F(d,n)=sum_{i=1}^nh(itimes d)S(i) F(d,n)=∑i=1nh(i×d)S(i)
发现 d d d很大的时候后面那个东西的取值就很小,但是 d d d很多,需要快速处理。
设定一个分界值
T
T
T,每次小于
T
T
T的部分我们就暴力用
F
F
F数组计算,大于
T
T
T的部分我们预处理出一个
G
(
d
,
i
,
j
)
=
∑
x
=
T
+
1
d
F
(
i
)
F
(
j
)
μ
(
d
)
G(d,i,j)=sum_{x=T+1}^dF(i)F(j)mu(d)
G(d,i,j)=x=T+1∑dF(i)F(j)μ(d)
然后整除分块计算。
这里的 k k k取 N 2 3 N^{frac{2}{3}} N32会平均一些,时间复杂度 O ( n 4 3 + Q n 2 3 ) O(n^{frac{4}{3}}+Qn^{frac{2}{3}}) O(n34+Qn32)
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define ll long long
using namespace std;
const ll N=2e5+10,P=1<<30;
ll q,n,m,cnt,pri[N],mu[N],S[N],sg[N],g[N],o[N];
vector<int>f[N],d[N];
bool v[N];
void prime(){
mu[1]=sg[1]=1;
for(ll i=2;i<N;i++){
if(!v[i])pri[++cnt]=i,mu[i]=-1,g[i]=2,sg[i]=2;
for(ll j=1;j<=cnt&&i*pri[j]<N;j++){
v[i*pri[j]]=1;
if(i%pri[j]==0){
g[i*pri[j]]=g[i]+1;
sg[i*pri[j]]=sg[i]/g[i]*g[i*pri[j]];
break;
}
mu[i*pri[j]]=-mu[i];g[i*pri[j]]=2;
sg[i*pri[j]]=sg[i]*sg[pri[j]];
}
}
for(ll i=1;i<N;i++)
for(ll j=i;j<N;j+=i)
(S[j]+=sg[j/i]*sg[j/i]*mu[i]%P)%=P;
return;
}
signed main()
{
freopen("math.in","r",stdin);
freopen("math.out","w",stdout);
prime();
scanf("%lld",&q);ll lim=2e5;
ll T=(ll)pow(lim,2.0/3.0)+1;
f[0].resize(lim+1);
for(ll i=1;i<=lim;i++){
f[i].push_back(0);
for(ll j=1;j<=lim/i;j++){
ll tmp=f[i][j-1];
f[i].push_back((tmp+S[i*j]*sg[j])%P);
}
}
d[T].resize((lim/T)*(lim/T)+1);
for(ll i=T+1;i<=lim;i++){
ll p=lim/i;
d[i].resize(p*p+1);
for(ll j=1,sum=0;j<=lim/i;j++)
for(ll k=j;k<=lim/i;k++)
d[i][(j-1)*p+k]=(d[i-1][(j-1)*o[i-1]+k]+f[i][j]*f[i][k]*mu[i])%P;
o[i]=p;
}
while(q--){
scanf("%lld%lld",&n,&m);
if(n>m)swap(n,m);ll ans=0;
for(ll i=1;i<=min(T,n);i++)
(ans+=1ll*f[i][n/i]*f[i][m/i]*mu[i]%P)%=P;
for(ll l=T+1,r;l<=n;l=r+1){
r=min(n/(n/l),m/(m/l));
(ans+=d[r][(n/l-1)*o[r]+m/l]-d[l-1][(n/l-1)*o[l-1]+m/l])%=P;
}
printf("%lldn",(ans+P)%P);
}
return 0;
}
最后
以上就是高大绿茶为你收集整理的YbtOJ#943-平方约数【莫比乌斯反演,平衡规划】正题的全部内容,希望文章能够帮你解决YbtOJ#943-平方约数【莫比乌斯反演,平衡规划】正题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复