• SPOJ (BNUOJ) LCM Sum


    LCM Sum


    Time Limit: 5000 ms     Case Time Limit: 5000 ms     Memory Limit: 262144 KB
    Submit: 4     Accepted: 0
    This problem will be judged on SPOJ. Original ID: LCMSUM.
    
    

    [Prev][Next]

    Description

    
    

    Given n, calculate the sum LCM(1,n) + LCM(2,n) + .. + LCM(n,n), where LCM(i,n) denotes the Least Common Multiple of the integers i and n.

    Input


    The first line contains T the number of test cases. Each of the next T lines contain an integer n.


    Output


    Output T lines, one for each test case, containing the required sum.

    Example

    Sample Input :
    3
    1
    2
    5

    Sample Output :
    1
    4
    55


    Constraints

    1 <= T <= 300000
    1 <= n <= 1000000

    
    

    Input


    Output


    Sample Input

    Sample Output

    Source

    own problem used for Codechef Snackdown Onsite
    卡时卡的好紧

    //思路 欧拉函数
    gcd(i,n)=k 求出所有的这样i的和 n*(phi[n/k]*(n/k)/2)*k
    lcm(i,n)=i*n/k; 所以 所有这样的i sigma(lcm(i,n))=n*[n*(phi[n/k]*(n/k)/2)8k]/k
    整理得 n*n*phi[n/k]/2/k 然后sqrt(n) 时间复杂度是 预处理欧拉函数时间+Qsqrt(N),这个超时、、、
    然后再整理,(i|n) sigma(lcm(i,n))=n*(n/k)*phi[n/k]/2; 把n/k 看成a 则 =n*a*phi[a]/2
    这样就可以预处理所有的 lcm(i,N) 1<=i<=N 值, 输出直接是O(1);
    //
    超时代码
    #include <iostream>
    #include <stdio.h>
    #include <math.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define N 1000001
    int phi[N];
    #define __int64 long long
    void set()//求欧拉函数
    {
        int i,j;
        for(i=2;i<N;i++)
          if(i%2)
            phi[i]=i;
          else
            phi[i]=i/2;
        for(i=3;i<N;i+=2)
         if(phi[i]==i)
           for(j=i;j<N;j+=i)
            phi[j]=phi[j]/i*(i-1);
    }
    int main()
    {
        set();
        int T;
        int m;
        __int64 n;
        __int64 sum;
        scanf("%d",&T);
        int i;
        while(T--)
        {
            scanf("%lld",&n);
            if(n==1) { printf("1\n");continue; }
            m=sqrt((double)n);
            sum=n*n*phi[n]/2;
            for(i=2;i<=m;i++)
             if(n%i==0)
             {
                 sum+=n*n*phi[n/i]/2/i;
                 if(i*i<n)
                 {
                     sum+=n*n*phi[i]/2/(n/i);
                 }
             }
             sum+=n;
            printf("%lld\n",sum);

        }
        return 0;
    }




    AC 代码

    #include <iostream> #include <stdio.h> #include <math.h> #include <string.h> #include <algorithm> using namespace std; #define N 1000001 #define __int64 long long __int64 phi[N]; __int64 ans[N]; void set() { __int64 i,j; for(i=2;i<N;i++) if(i%2) phi[i]=i; else phi[i]=i/2; for(i=3;i<N;i+=2) if(phi[i]==i) for(j=i;j<N;j+=i) phi[j]=phi[j]/i*(i-1); ans[1]=1; for(i=2;i<N;i++) ans[i]=i*phi[i]/2+1; __int64 k;//开始变量定义成int 计算过程中导致超过 int范围 for(i=2;i<=1000;i++) { ans[i*i]+=i*phi[i]/2; for(j=i*i+i,k=i+1;j<N;j+=i,k++) ans[j]+=i*phi[i]/2+k*phi[k]/2; } } int main() { set(); int T; int n; scanf("%d",&T); while(T--) { scanf("%d",&n); printf("%lld\n",ans[n]*n); } return 0; }
  • 相关阅读:
    深入浅出之正则表达式(二)
    ==和equlas的区别
    温故知新 javascript 正则表达式
    SQL Server高级内容之子查询和表链接
    C语言访问webservice小例子
    jquery菜单伸缩效果
    电影资源下载网站推荐
    百度云使用迅雷下载资源
    字符编码
    7_2 利用 const 引用避免复制
  • 原文地址:https://www.cnblogs.com/372465774y/p/2740066.html
Copyright © 2020-2023  润新知