题解:P3327 [SDOI2015] 约数个数和

· · 题解

纪念自己独立推出来的第一道(对我来说)比较进阶的莫比乌斯反演题。

这篇题解将会给出一个完全不需要 d(ij)=\sum\limits_{x|i}\sum\limits_{y|j}[\gcd(x,y)=1] 这个结论的做法,希望能给你一些帮助。

题解

推式子!

\begin{aligned}& \sum\limits_{i=1}^n\sum\limits_{j=1}^md(ij) \\=& \sum\limits_{i=1}^n\sum\limits_{j=1}^m\sum\limits_{d|ij}1 \\=& \sum\limits_{d=1}^{nm}\sum\limits_{i=1}^n\sum\limits_{\frac d{\gcd(d,i)}|j}^m 1\text{(把 }d \text{ 提到外面)}\\=& \sum\limits_{d=1}^{nm}\sum\limits_{i=1}^n\lfloor\frac{m\gcd(d,i)}d\rfloor\\=& \sum\limits_{g=1}^n\sum\limits_{g|i}^n\sum\limits_{g|d}^{nm}[\gcd(d,i)=g]\lfloor\frac{mg}d\rfloor \text{(枚举 } g=\gcd(d,i) \text{)} \end{aligned}

因为 d\le mg 时才有贡献,所以我们可以将 d 的上限改为 mg,然后将整除消去(下式的 id 都是上式的 \frac 1g 倍):

\begin{aligned}&= \sum\limits_{g=1}^n\sum\limits_{i=1}^{\lfloor\frac ng\rfloor}\sum\limits_{d=1}^{m}[\gcd(d,i)=1]\lfloor\frac md\rfloor\\&= \sum\limits_{g=1}^n\sum\limits_{i=1}^{\lfloor\frac ng\rfloor}\sum\limits_{d=1}^{m}\lfloor\frac md\rfloor\sum\limits_{k|\gcd(i,d)}\mu(k)\text{(有点感觉了!反演一下)}\\&= \sum\limits_{k=1}^n\mu(k)\sum\limits_{g=1}^{\lfloor\frac nk\rfloor}\sum\limits_{k|i}^{\lfloor\frac ng\rfloor}\sum\limits_{k|d}^{m}\lfloor\frac md\rfloor\text{(把 }k\text{ 提出去,}g\text{ 的上限也相应的变化)}\\&= \sum\limits_{k=1}^n\mu(k)\sum\limits_{k|d}^{m}\lfloor\frac md\rfloor\sum\limits_{g=1}^{\lfloor\frac nk\rfloor}\sum\limits_{k|i}^{\lfloor\frac ng\rfloor}1\text{(交换求和顺序)}\\&= \sum\limits_{k=1}^n\mu(k)\sum\limits_{d=1}^{\lfloor\frac mk\rfloor}\lfloor\frac m{kd}\rfloor\sum\limits_{g=1}^{\lfloor\frac nk\rfloor}\lfloor\frac n{kg}\rfloor\text{(依旧消掉整除)} \end{aligned}

是不是有点眼熟?设 S(x)=\sum\limits_{i=1}^x\lfloor\frac xi\rfloor,则:

然后我们就做完了!$\mu$ 可以 $\mathcal O(n)$ 线性筛预处理,$S(x)$ 可以 $\mathcal O(n\sqrt n)$ 整除分块预处理,求的时候也可以整除分块做到 $\mathcal O(T\sqrt n)$(假设 $n$,$m$ 同阶),显然足够通过本题。 ### 代码 这个题没有取模!!! ```cpp #define int long long #define fo(i,l,r) for(int i=l;i<=r;i++) int cnt,pr[50005],mu[50005],S[50005]; bitset<50005>np; void init(){ mu[1]=1; fo(i,2,50000){ if(!np[i])pr[++cnt]=i,mu[i]=-1; fo(j,1,cnt) if(i*pr[j]>50000)break; else{ np[i*pr[j]]=1; if(i%pr[j]==0){mu[i*pr[j]]=0;break;} mu[i*pr[j]]=-mu[i]; } mu[i]+=mu[i-1]; } fo(i,1,50000){ int l=1; while(l<=i){ int r=i/(i/l); S[i]+=(r-l+1)*(i/l),l=r+1; } } } int n,m; void solve(){ cin>>n>>m; if(n>m)swap(n,m); int l=1,ans=0; while(l<=n){ int r=min(n/(n/l),m/(m/l)); ans+=(mu[r]-mu[l-1])*S[n/l]*S[m/l],l=r+1; } cout<<ans<<'\n'; } signed main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int T=1; cin>>T,init(); while(T--)solve(); return 0; } ``` 神曲推荐:Radium - Sydosys