SP5971 LCMSUM 数论
Posted lishuyu2003
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SP5971 LCMSUM 数论相关的知识,希望对你有一定的参考价值。
题目要我们求这个:
\[\sum_i=1^n lcm(i,n)\]
开始化式子:
\[\sum_i=1^n \fraci*ngcd(i,n)\]
\[\sum_d|n \sum_i=1^\fracnd i*n[gcd(i,\fracnd)=1]\]
\[n*\sum_d|n\sum_i=1^di[gcd(i,d)=1]\]
注意那个\(\sum_i=1^di[gcd(i,d)=1]\)是求\([1,d]\)中所有与\(d\)互质的数的和,可以证明当\(d>1\)时,它等于\(\fracd*\phi(d)2\),证明如下:
对于每个\(i\),若它与\(d\)互质,则\(d-i\)也与\(d\)互质,每一对\(i\)与\(d-i\)的和为\(d\),所以平均每个与\(d\)互质的数的值为\(\fracd2\),一共有\(\phi(d)\)个与\(d\)互质的数,所以他们的和为\(\fracd*\phi(d)2\)
而与\(1\)互质的数的和显然为\(1\)
所以上式可化为
\[n*\big((\sum_d|n,d>1\fracd*\phi(d)2)+1\big)\]
\[ \big( \fracn2*\sum_d|n,d>1d*\phi(d)\big)+n\]
设\(g(n)=\sum_d|nd*\phi(d)\),上式化为:
\[\fracn2*(g(n)-1)+n\]
其中\(g(n)\)是一个积性函数,可以\(O(n)\)筛出
每次询问是\(O(1)\)的
总时间复杂度为\(O(n+T)\)
关于如何线筛出\(g(n)\):
\(n\)为质数:\(g(n)=1+n*\phi(n)=1+n*(n-1)\)
\(n=p^k\):
\[g(n)=1+\sum_i=1^kp^i*\phi(p^i)\]
\[=1+\sum_i=1^kp^i*p^i-1*(p-1)\]
\[=1+(p-1)\sum_i=1^kp^2i-1\]
\[=1+(p-1)\fracp^2k+1-pp^2-1\]
\[ =1+\fracp^2k+1-pp+1\]
\(n\)的最小质因子为\(p\):\(g(n)=g(n'*p^k)=g(n')*g(p^k)\)
然后就可以线性筛了
代码:
#include<bits/stdc++.h>
using namespace std;
#define N 1000007
#define ll long long
const int lim=1e6;
int pr[N],cnt,pk[N];
bool zhi[N];
ll f[N];
void Init()
int i,j;
f[1]=1;
for(i=2;i<=lim;i++)
if(!zhi[i])
pr[++cnt]=i,f[i]=1+1ll*i*(i-1);
pk[i]=i;
for(j=1;j<=cnt&&i*pr[j]<=lim;j++)
int p=pr[j],x=i*p;
zhi[x]=true;
if(i%p==0)
pk[x]=pk[i]*p;
f[x]=f[x/pk[x]]*(1+(1ll*pk[x]*pk[x]*p-p)/(p+1));
break;
pk[x]=p;
f[x]=f[i]*f[p];
for(i=1;i<=lim;i++)
f[i]=1ll*(f[i]-1)*i/2+i;
int main()
int t,n;
Init();
scanf("%d",&t);
while(t--)
scanf("%d",&n);
printf("%lld\n",f[n]);
return 0;
我原本的做法是用\(\mu\)暴力拆\([gcd(i,d)=1]\),但是那样做的复杂度是\(O(n\log n)\)的,也没有这个做法巧妙,这里就不讲了。
以上是关于SP5971 LCMSUM 数论的主要内容,如果未能解决你的问题,请参考以下文章