[luogu4466]和与积

令$d=gcd(i,j)$,$i'=frac{i}{d}$,$j'=frac{j}{d}$,则$(i',j')=1$,可得$(i'+j',i'j')=1$(假设有公因子$p$,必然有$p|i'或j'$,又因为$p|(i'+j')$,则$p|i'$且$p|j'$,与$(i',j')=1$矛盾)

根据这些,原式$(i+j)|ijiff(i'+j')|i'j'diff (i'+j')|d$

考虑枚举$i'$和$j'$,那么答案即$sum_{i=1}^{n}sum_{j=i+1}^{n}[gcd(i,j)=1]lfloorfrac{n}{(i+j)j} floor$

先对第一维进行反演,得到$sum_{d=1}^{n}mu(d)sum_{i=1}^{lfloorfrac{n}{d} floor}sum_{j=i+1}^{lfloorfrac{n}{d} floor}lfloorfrac{n}{(i+j)jd^{2}} floor$

可以发现,右式不为0必要条件为$i<jlelfloor sqrt{frac{n}{d^{2}}} floor$,因此$dle sqrt{n}$,暴力复杂度即$nint_{1}^{sqrt{n}}x^{-2}dx=o(n)$

考虑先枚举$j$再对$i+j$数论分块,时间复杂度降为$n^{frac{3}{4}}int_{1}^{sqrt{n}}x^{-frac{3}{2}}dx=o(n^frac{3}{4})$,可以通过

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 100005
 4 int n,p[N],vis[N],mu[N];
 5 long long ans;
 6 long long calc(int n,int k){
 7     long long ans=0;
 8     for(int i=k+1,j;(i<=n)&&(i<2*k);i=j+1){
 9         j=min(n/(n/i),2*k-1);
10         ans+=(n/i)*(j-i+1);
11     }
12     return ans;
13 }
14 int main(){
15     scanf("%d",&n);
16     mu[1]=1;
17     for(int i=2;i<N-4;i++){
18         if (!vis[i]){
19             p[++p[0]]=i;
20             mu[i]=-1;
21         }
22         for(int j=1;(j<=p[0])&&(i*p[j]<N-4);j++){
23             vis[i*p[j]]=1;
24             if (i%p[j])mu[i*p[j]]=mu[i]*mu[p[j]];
25             else{
26                 mu[i*p[j]]=0;
27                 break;
28             }
29         }
30     }
31     int d=(int)sqrt(n);
32     for(int i=1;i<=d;i++){
33         int m=n/(i*i),dd=(int)sqrt(m);
34         for(int j=1;j<=dd;j++)ans+=mu[i]*calc(m/j,j);
35     }
36     printf("%lld",ans);
37 }
View Code
原文地址:https://www.cnblogs.com/PYWBKTDA/p/13834757.html