題目大意:求gcd(1,2)+gcd(1,3)+gcd(2,3)+...+gcd(n-1,n)
-----------------------------------------------------------------
設f(i)=gcd(1,n)+...+gcd(n-1,n),則答案S(n)=f(2)+...+f(n)
如何求f
設g(n,i)表示滿足gcd(x,n)=1且x<n的x個數,則f(n)=sum{i*g(n,i):i|n}
gcd(x,n)=i的充要條件是x/i和n/i互質,所以gcd(n,i)=phi(n/i)
計算一片f用類似篩法的方法
------------------------------------
LuoguP2398題目描述
for i=1 to n
for j=1 to n
sum+=gcd(i,j)
給出n求sum. gcd(x,y)表示x,y的最大公約數.
----------------------------------------
很類似,在加上一個nf=gcd(1,n)+...+gcd(n,n) f和nf加起來就行了
#include <iostream> #include <cstdio> #include <cstring> using namespace std; typedef long long ll; const int N=1e5+5; ll n,ans=0; int phi[N]; void phiTable(int n){ phi[1]=1; for(int i=2;i<=n;i++) if(!phi[i]) for(int j=i;j<=n;j+=i){ if(!phi[j]) phi[j]=j; phi[j]=phi[j]/i*(i-1); } } ll f[N],nf[N]; int main(int argc, const char * argv[]) { cin>>n; phiTable(n); for(int i=1;i<=n;i++) for(int j=i;j<=n;j+=i){ nf[j]+=i*phi[j/i]; if(j!=i) f[j]+=i*phi[j/i]; } for(int i=1;i<=n;i++) ans+=f[i]+nf[i]; cout<<ans; return 0; }