1. 程式人生 > >51nod 1188 最大公約數之和 V2

51nod 1188 最大公約數之和 V2

floor names log mes phi cst info printf body

技術分享圖片
第二個\( O(T\sqrt(n)) \)復雜度T了..T了..T了...天地良心,這能差多少?!
於是跑去現算(。
\[ \sum_{i=1}^{n-1}\sum_{j=i+1}^{n}gcd(i,j) \]
\[ \sum_{d=1}^{n}d\sum_{i=1}^{n-1}\sum_{j=i+1}^{n}[gcd(i,j)==d] \]
\[ \sum_{d=1}^{n}d(\sum_{j=1}^{n}\sum_{i=1}^{j}[gcd(i,j)==d]-\sum_{j=1}^{n}[gcd(j,j)==d]) \]
\[ \sum_{d=1}^{n}d(\sum_{j=1}^{\left \lfloor \frac{n}{d} \right \rfloor}\sum_{i=1}^{j}[gcd(i,j)==1]-1) \]


\[ \sum_{d=1}^{n}d(\sum_{j=1}^{\left \lfloor \frac{n}{d} \right \rfloor}\phi(j)-1) \]
然後與\( O(nlnn) \)處理出所有答案。

#include<iostream>
#include<cstdio>
using namespace std;
const int N=5000005,m=5000000;
int T,n,phi[N],q[N],tot;
long long s[N],ans[N],con;
bool v[N];
int main()
{
    phi[1]=1;
    for(int
i=2;i<=m;i++) { if(!v[i]) { q[++tot]=i; phi[i]=i-1; } for(int j=1;j<=tot&&i*q[j]<=m;j++) { int k=i*q[j]; v[k]=1; if(i%q[j]==0) { phi[k]=phi[i]*q[j]; break
; } phi[k]=phi[i]*(q[j]-1); } } for(int i=1;i<=m;i++) for(int j=2;j<=m/i;j++) ans[i*j]+=phi[j]*i; for(int i=1;i<=m;i++) ans[i]+=ans[i-1]; scanf("%d",&T); while(T--) { scanf("%d",&n); printf("%lld\n",ans[n]); } return 0; }

51nod 1188 最大公約數之和 V2