zoukankan      html  css  js  c++  java
  • uva-11426-数论

    https://vjudge.net/problem/UVA-11426#author=0

    求 SUM{ gcd(i,j) | 1<=i<j<=n}, n<4000001。

    令f(n)=gcd(1,n)+gcd(2,n)+...+gcd(n-1,n),

    则 S(n)=f(2)+f(3)+...+f(n) 即为我们所求答案,问题转化为求解f(n)。

      可以看出对于f(n)的所有项的答案一定是n的因子,我们不妨令g(x,i)表示因子i对应的f(n)里的项x的个数,

    那么f(n)=SUM{ i*g(x,i) | i为n的因子且0<x<n}  有gcd(x,n)==i  -->  gcd(x/i,n/i)==1 ,所以因子i对应的x的个数就

    等价于与n/i互质且小于n/i的数的个数,这个就可以用phi来求解了。

       在求f的时,一开始是用的O(N*sqrt(N))来一个一个找会T,太蠢了。只要和打表phi一样利用类似于埃筛

    的方法就可以降到O(N*log(N))了。

      

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define LL long long 
     4 const int maxn=4000001;
     5 LL f[maxn];
     6 int phi[maxn];
     7 void init(){
     8     phi[1]=1;
     9     int m=sqrt(maxn+0.5);
    10     for(int i=2;i<maxn;++i){
    11         if(!phi[i]){
    12             for(int j=i;j<maxn;j+=i){
    13                 if(!phi[j]) phi[j]=j;
    14                 phi[j]=phi[j]/i*(i-1);
    15             }
    16         }
    17     }
    18     for(int i=1;i<maxn;++i){
    19         for(int j=i*2;j<maxn;j+=i){
    20             f[j]+=i*phi[j/i];
    21         }
    22     }
    23     for(int i=3;i<maxn;++i) f[i]+=f[i-1];
    24 }
    25 int main(){
    26     init();
    27     int n;
    28     while(scanf("%d",&n)&&n){
    29         printf("%lld
    ",f[n]);
    30     }
    31     return 0;
    32 } 
  • 相关阅读:
    Mutex和RWMutex
    内核态和用户态
    runtime源码
    goroutine的结束与通信
    进程线程协程
    堆和栈
    array和slice区别
    逃逸分析
    单例模式
    WaitGroup用法
  • 原文地址:https://www.cnblogs.com/zzqc/p/9364628.html
Copyright © 2011-2022 走看看