zoukankan      html  css  js  c++  java
  • spoj LCMSUM sigma(lcm(i,n));


    Problem code: LCMSUM

    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

    题意:sigma(lcm(i,n)) ; 1<=i<=n

    思路:题意倒是很简单,有类似的题目sigma(gcd(i,n)) ;1<=i<=n;

        一看就是果然是同类型的。

    gcd(i,n)的题目 http://www.cnblogs.com/tom987690183/p/3247439.html

    这个是求lcm()最小公倍数.

    同样的思路,我们枚举gcd() = d 则在[ 1 , n ]中与n最大公约数为d的值有euler(n/d)个.

    这些数的和为euler(n/d)*n/2;  我们知道lcm = x*n/(gcd(x,n)) = > x*n/d ;

    因为与n gcd() = d的数字为x1,x2,x3....

    根据lcm = x*n/(gcd(x,n)) 可以得到 (n/d)*(x1+x2+x3...) => [euler(n/d)*n/2]*(n*d);

    这里需要注意的是当gcd(i,n) = n的时候,用euler(n)*n/2算的时候是不对的,就特判吧。

    这样的思路,我们就可以试一下打欧拉表opl[ ],需要时间o(N);

    然后对于n,要用sqrt(n)的时间。

    T*sqrt(n)+o(N) = 3^8+10^6.果断超时。以为能ac,吼吼。

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<cstring>
     4 #include<cstdlib>
     5 using namespace std;
     6 typedef long long LL;
     7 
     8 const int maxn = 1e6+3;
     9 int opl[maxn];
    10 void init()
    11 {
    12     for(int i=1;i<maxn;i++) opl[i] = i;
    13     for(int i=2;i<maxn;i++)
    14     {
    15         if(opl[i]==i) opl[i] = i-1;
    16         else continue;
    17         for(int j=i+i;j<maxn;j=j+i)
    18             opl[j] = opl[j]/i*(i-1);
    19     }
    20 }
    21 int main()
    22 {
    23     int T;
    24     LL n;
    25     init();
    26     scanf("%d",&T);
    27     while(T--)
    28     {
    29         scanf("%lld",&n);
    30         LL sum = 0;
    31         for(LL i=1;i*i<=n;i++)
    32         {
    33             if(n%i==0)
    34             {
    35                 if(i!=n)
    36                 sum = sum + (n/i)*(opl[n/i]*n/2);
    37                 LL tmp = n/i;
    38                 if(tmp!=i && tmp!=n)
    39                     sum = sum + i*(opl[i]*n/2);
    40             }
    41         }
    42         printf("%lld
    ",sum+n);
    43     }
    44     return 0;
    45 }
    View Code

    这样的话,是不行了。

    原始相当于

    也就能转化为(easy)

    这样的话,我们就能单独的求出euler(a)*a/2;然后用它来筛选g[n]的值。

    (x|n的意思代表 n是x的倍数)

    我们想到在第一种方法里,我们用sqrt(n)来求它的因子的方法。

    同理,逆向一下就好。

    这样我们只需要o(N) 的时间对g[]进行筛选。总的预处理时间

    3*o(N) = > 3*10^6; 

    完毕。

    需要注意的是,我们没有把gcd() = n的情况包含进去,所以最后要+n。

    代码:

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<cstring>
     4 #include<cstdlib>
     5 using namespace std;
     6 typedef long long LL;
     7 
     8 const int maxn = 1e6+3;
     9 LL opl[maxn];
    10 LL g[maxn];
    11 void init()
    12 {
    13     for(int i=1;i<maxn;i++) opl[i] = i;
    14     //这种方法筛选素数,不用和以前一样要先刷素数,还开num[];
    15     for(int i=2;i<maxn;i++) 
    16     {
    17         if(opl[i]==i)
    18             opl[i] = i-1;
    19         else continue;
    20         for(int j=i+i;j<maxn;j=j+i)
    21             opl[j] = opl[j]/i*(i-1);
    22     }
    23     for(int i=2;i<maxn;i++){
    24         opl[i] = opl[i]*i/2;
    25         g[i] = opl[i];
    26     }
    27     for(long long i=2;i<=1000;i++) //这里的i 不能用int,肯定会超int的
    28     {
    29         for(long long j=i*i,k=i;j<maxn;j=j+i,k++)
    30         if(i!=k) //不重复
    31             g[j] = g[j] + opl[i]+opl[k];
    32         else g[j] = g[j] + opl[i];
    33     }
    34 }
    35 int main()
    36 {
    37     init();
    38     int T;
    39     LL n;
    40     scanf("%d",&T);
    41     while(T--)
    42     {
    43         scanf("%lld",&n);
    44         printf("%lld
    ",g[n]*n+n);
    45     }
    46     return 0;
    47 }
  • 相关阅读:
    Servlet3.0之五:servlet3.0下的web.xml
    RESTLET开发实例(二)使用Component、Application的REST服务
    并发容器之ConcurrentLinkedDeque
    script的onerror事件支持情况调查
    纯CSS后台框架
    浏览器对width与height的最大值限制
    DOM系统中的各种队列
    跨域的异步请求四
    JSON parse在各浏览器的兼容性列表
    在IE6~8下创建HTML5新标签
  • 原文地址:https://www.cnblogs.com/tom987690183/p/3942403.html
Copyright © 2011-2022 走看看