码迷,mamicode.com
首页 > 其他好文 > 详细

51nod 1188 最大公约数之和 V2

时间:2018-01-19 22:21:09      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:pre   i++   ons   body   答案   多少   while   class   --   

技术分享图片
第二个\( 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

标签:pre   i++   ons   body   答案   多少   while   class   --   

原文地址:https://www.cnblogs.com/lokiii/p/8318854.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!