zoukankan      html  css  js  c++  java
  • UVa10426

     GCD Extreme (II)

    Input: Standard Input Output:

    Standard Output  

    Given the value of N, you will have to find the value of G. The definition of G is given below:

      Here GCD(i,j) means the greatest common divisor of integer i and integer j.   For those who have trouble understanding summation notation, the meaning of G is given in the following code: G=0; for(i=1;i<N;i++) for(j=i+1;j<=N;j++) {     G+=gcd(i,j); } /*Here gcd() is a function that finds the greatest common divisor of the two input numbers*/   Input The input file contains at most 100 lines of inputs. Each line contains an integer N (1<N<4000001). The meaning of N is given in the problem statement. Input is terminated by a line containing a single zero.   Output For each line of input produce one line of output. This line contains the value of G for the corresponding N. The value of G will fit in a 64-bit signed integer.   Sample Input                          

     10 100 200000 0  

    Output for Sample Input

    67 13015 143295493160  

    Problemsetter: Shahriar Manzoor

    Special Thanks: Syed Monowar Hossain

    /* 【题意】

    求sum(gcd(i,j),1<=i<j<=n)1<n<4000001

    【题解】 1.建立递推关系,s(n)=s(n-1)+gcd(1,n)+gcd(2,n)+……+gcd(n-1,n);

    2.设f(n)=gcd(1,n)+gcd(2,n)+……+gcd(n-1,n)。

    gcd(x,n)=i是n的约数(x<n),按照这个约数进行分类。设满足gcd(x,n)=i的约束有g(n,i)个,则有f(n)=sum(i*g(n,i))。

    而gcd(x,n)=i等价于gcd(x/i,n/i)=1,因此g(n,i)等价于phi(n/i).phi(x)为欧拉函数。

    3.降低时间复杂度。用筛法预处理phi[x]表

    用筛法预处理f(x)->枚举因数,更新其所有倍数求解。

    */

    /* 欧拉函数的应用,以后看到互质的数第一个就要想到欧拉函数。今天又学到了好多家伙。 欧拉定理: 欧拉定理表明,若n,a为正整数,且n,a互质,(a,n) = 1,则a^φ(n) ≡ 1 (mod n)   费马小定理: 且(a,p)=1,那么 a^(p-1) ≡1(mod p) 假如p是质数,且a,p互质,那么 a的(p-1)次方除以p的余数恒等于1 */

      1 //1285ms
      2 
      3 #include<stdio.h>
      4 #include<string.h>
      5 #include<algorithm>
      6 #include<math.h>
      7 #include<queue>
      8 #include<set>
      9 #include<vector>
     10 #include<bitset>
     11 using namespace std;
     12 typedef long long ll;
     13 
     14 const int M=4000010;
     15 int phi[M];
     16 ll s[M],f[M];//f[n]=sum(phi[i]*j)    (i*j=n) (去掉n*phi[1],因为gcd(n,n)不符合题意!!)
     17 
     18 int get(){
     19     char c;
     20     int res=0;
     21     while(c=getchar(),!isdigit(c));
     22     do{
     23         res=(res<<3)+(res<<1)+(c-'0');
     24     }while(c=getchar(),isdigit(c));
     25     return res;
     26 }
     27 
     28 
     29 void phi_table()//类似素数刷表!! 
     30 {
     31     phi[1]=1;
     32     for(int i=2;i<M;i++)phi[i]=i;    
     33     for(int i=2;i<M;i+=2)phi[i]/=2;    
     34     for(int i=3;i<M;i+=2)
     35     if(phi[i]==i)//说明i是素数!!! 
     36     for(int j=i;j<M;j+=i)
     37     {
     38         phi[j]-=phi[j]/i;//保证i是素数且是j的素因子!!! 
     39     }
     40 }  
     41 
     42 int main()
     43 {
     44     int n,i,j,k;
     45     phi_table();
     46     memset(f,0,sizeof(f));
     47     phi[1]=0;
     48     for(i=1;i<(int)sqrt(M);i++)
     49     {
     50         f[i*i]+=phi[i]*i;
     51         for(n=i*i+i;n<M;n+=i)
     52         f[n]+=(ll)(i*phi[n/i]+n/i*phi[i]);//之前令phi[1]=0;因为gcd(n,n)不符合题意!! 
     53     }        
     54     s[2]=1;
     55     for( n=3;n<M;n++)    s[n]=s[n-1]+f[n];
     56     while(1)
     57     {
     58         n=get();
     59         if(n==0)break;
     60         printf("%lld
    ",s[n]);
     61     }
     62     return 0;
     63 }
     64 
     65 
     66 
     67 
     68 
     69 //2382ms
     70 #include<stdio.h>
     71 #include<string.h>
     72 #include<algorithm>
     73 #include<math.h>
     74 #include<queue>
     75 #include<set>
     76 #include<vector>
     77 #include<bitset>
     78 using namespace std;
     79 typedef long long ll;
     80 
     81 const ll M=4000010;
     82 ll phi[M];
     83 ll s[M],f[M];
     84 
     85 void phi_table()//类似素数刷表!! 
     86 {
     87     phi[1]=1;
     88     for(int i=2;i<M;i++)phi[i]=i;    
     89     for(int i=2;i<M;i+=2)phi[i]/=2;    
     90     for(int i=3;i<M;i+=2)
    
     91     if(phi[i]==i)//说明i是素数!!! 
     92     for(int j=i;j<M;j+=i)
     93     {
     94         phi[j]-=phi[j]/i;//保证i是素数且是j的素因子!!! 
     95     }
     96 }  
     97 int main()
     98 {
     99     phi_table();
    100     memset(f,0,sizeof(f));
    101     for(int i=1;i<M;i++)
    102     for(int n=i+i;n<M;n+=i)
    103         f[n]+=i*phi[n/i];
    104     s[2]=1;
    105     for(int n=3;n<M;n++)    s[n]=s[n-1]+f[n];
    106     int n;
    107     while(scanf("%d",&n)==1&&n)
    108     {
    109         printf("%lld
    ",s[n]);
    110     }
    111     return 0;
    112 }
    113 
    114 
    115 
    116 
    117 
    118 #include<stdio.h>
    119 #include<string.h>
    120 #include<algorithm>
    121 #include<math.h>
    122 #include<queue>
    123 #include<set>
    124 #include<vector>
    125 #include<bitset>
    126 using namespace std;
    127 typedef long long ll;
    128 
    129 const ll M=4100000;
    130 ll phi[2*M];
    131 ll s[M],f[M];
    132 
    133 void phi_table()//类似素数刷表!! 
    134 {
    135     for(int i=2;i<=M;i++)phi[i]=0;
    136     phi[1]=1;
    137     for(int i=2;i<=M;i++)
    138     if(!phi[i])//说明i是素数!!! 
    139     for(int j=i;j<=M;j+=i)
    140     {
    141         if(!phi[j])phi[j]=j;
    142         phi[j]=phi[j]/i*(i-1);//保证i是素数且是j的素因子!!! 
    143     }
    144 }  
    145 int main()
    146 {
    147     phi_table();
    148     memset(f,0,sizeof(f));
    149     for(int i=1;i<=M;i++)
    150     for(int n=i+i;n<=M;n+=i)
    151         f[n]+=i*phi[n/i];
    152     s[2]=1;
    153     for(int n=3;n<=M;n++)    s[n]=s[n-1]+f[n];
    154     int n;
    155     while(scanf("%d",&n)==1&&n)
    156     {
    157         printf("%lld
    ",s[n]);
    158     }
    159     return 0;
    160 }
    View Code
  • 相关阅读:
    git分支管理策略
    git解决冲突
    git分支创建和合并
    git连接远程库
    git删除文件
    git撤销修改
    4k测试网站
    Windows10通过TightVNC远程连接Ubuntu18.04
    robot报告合并输出
    python 传参中的*和**
  • 原文地址:https://www.cnblogs.com/skykill/p/3231188.html
Copyright © 2011-2022 走看看