一、题目描述:
给定 $a_1,a_2,\cdots,a_N$,求
$\sum_{i=1}^N\sum_{j=1}^N \mathrm{lcm}(a_i,a_j)$的值。
数据范围:$1\le n,a_i\le 5\times 10^4$ 。
二、解题思路:
这个题绝对有必要写一篇题解。
首先就是题目中的式子的转化。
一个式子如果含有未知的要进行函数操作的数,便是难以化简的。
发现题目保证了 $a_i\le 5\times 10^4$ 看了题解,于是可以记录数字的出现次数。
于是转化为求 $\sum_{i=1}^{n}\sum_{j=1}^{n}lcm(i,j)\times c_i\times c_j$ 。
好,开始愉快地推式子吧!
$$\sum_{i=1}^{n}\sum_{j=1}^{n}lcm(i,j)\times c_i\times c_j=$$
$$\sum_{i=1}^{n}\sum_{j=1}^{n}\frac{i\times j\times c_i\times c_j}{gcd(i,j)}=$$
$$\sum_{d=1}^{n}\sum_{i=1}^{n}\sum_{j=1}^{n}[gcd(i,j)=d]\frac{i\times j\times c_i\times c_j}{d}=$$
$$\sum_{d=1}^{n}\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{d}\rfloor}[gcd(i,j)=1]i\times j\times c_{id}\times c_{jd}\times d$$
$$令f(x,d)=\sum_{i=1}^{x}\sum_{j=1}^{x}[gcd(i,j)=1]i\times j\times c_{id}\times c_{jd}$$
$$则原式等于\sum_{d=1}^{n}d\times f(\lfloor\frac{n}{d}\rfloor,d)$$
$$f(\lfloor\frac{n}{d}\rfloor,d)=\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{d}\rfloor}[gcd(i,j)=1]i\times j\times c_{id}\times c_{jd}=$$
$$\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{k\mid gcd(i,j)}\mu(k)\times i\times j\times c_{id}\times c_{jd}=$$
$$\sum_{k=1}^{\lfloor\frac{n}{d}\rfloor}\mu(k)\times k^2\times \sum_{i=1}^{\lfloor\frac{n}{dk}\rfloor} \sum_{j=1}^{\lfloor\frac{n}{dk}\rfloor}i\times j\times c_{idk}\times c_{jdk}$$
$$再令g(x,m)=\sum_{i=1}^{x}\sum_{j=1}^{x}i\times j\times c_{im}\times c_{jm}$$
$$则f(\lfloor\frac{n}{d}\rfloor,d)=\sum_{k=1}^{n}g(\lfloor\frac{n}{dk}\rfloor,d\times k)\times \mu(k)\times k^2$$
$$g(\lfloor\frac{n}{dk}\rfloor,d\times k)=\sum_{i=1}^{\lfloor\frac{n}{dk}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{dk}\rfloor}i\times j\times c_{idk}\times c_{jdk}=$$
$$\left(\sum_{i=1}^{\lfloor\frac{n}{dk}\rfloor}i\times c_{idk}\right) \times \left(\sum_{j=1}^{\lfloor\frac{n}{dk}\rfloor}j\times c_{jdk}\right)$$
$$原式=\sum_{d=1}^{n}\sum_{k=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{i=1}^{\lfloor\frac{n}{dk}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{dk}\rfloor}d\times i\times j\times c_{idk}\times c_{jdk}\times \mu(k)\times k^2$$
$$令T=d\times k$$
$$原式=\sum_{T=1}^{n}T\times \sum_{i=1}^{\lfloor\frac{n}{T}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{T}\rfloor}i\times j\times c_{iT}\times c_{jT}\times \sum_{k\mid T} \mu(k)\times k=$$
$$\sum_{T=1}^{n}T\times \left(\sum_{i=1}^{\lfloor\frac{n}{T}\rfloor}i\times c_{iT}\right)^2\times \sum_{k\mid T} \mu(k)\times k$$
推个式子给我人推麻了$qwq$。
现在可以做了,时间复杂度 $O(nIn\ n)$ 。
三、完整代码:
1 #include<iostream> 2 #define N 50010 3 #define lim 50000 4 #define ll long long 5 using namespace std; 6 int n,cnt; 7 ll ans,g[N],c[N]; 8 int p[N],f[N],mu[N],vis[N]; 9 void pre_work() 10 { 11 mu[1]=1; 12 for(int i=2;i<=lim;i++) 13 { 14 if(!vis[i]) p[++cnt]=i,mu[i]=-1; 15 for(int j=1;j<=cnt&&p[j]*i<=lim;j++) 16 { 17 vis[i*p[j]]=1; 18 if(i%p[j]==0) break; 19 mu[i*p[j]]=-mu[i]; 20 } 21 } 22 for(int i=1;i<=lim;i++) 23 f[i]=mu[i]*i; 24 for(int i=1;i<=lim;i++) 25 for(int j=i;j<=lim;j+=i) 26 g[j]+=f[i]; 27 } 28 ll s(int m,int d) 29 { 30 ll res=0; 31 for(int i=1;i<=m;i++) 32 res+=i*c[i*d]; 33 return res*res; 34 } 35 int main() 36 { 37 cin>>n;pre_work(); 38 for(int i=1,x;i<=n;i++) 39 cin>>x,c[x]++; 40 for(int i=1;i<=lim;i++) 41 ans+=g[i]*i*s(lim/i,i); 42 cout<<ans<<'\n'; 43 return 0; 44 }
四、写题心得:
气死,推的式子比代码还长呜呜呜。收获经验如下:
$1、可以将数本身转化为出现次数进行计算。=> Exp++!$
$2、换元大概是一个莫比乌斯反演中一个比较常见的技巧吧,需要多练习。=> Exp++!$