• PE530 : GCD of Divisors


    [egin{eqnarray*}
    ans&=&sum_{i=1}^nf(i)\
    &=&sum_{i=1}^nsum_{d|i}gcd(d,frac{i}{d})\
    &=&sum_{i=1}^nsum_{d|i}sum_{k|d,k|frac{i}{d}}varphi(k)\
    &=&sum_{k=1}^nvarphi(k)sum_{k^2|i}sigma_0(frac{i}{k^2})\
    &=&sum_{k=1}^nvarphi(k)sum_{i=1}^{lfloorfrac{n}{k^2} floor}lfloorfrac{n}{k^2i} floor\
    &=&sum_{k=1}^{sqrt{n}}varphi(k)S(lfloorfrac{n}{k^2} floor)
    end{eqnarray*}]

    其中

    [S(n)=sum_{i=1}^nlfloorfrac{n}{i} floor]

    枚举所有$k$,然后分段计算$S$即可。

    时间复杂度

    [egin{eqnarray*}
    T(n)&=&O(sqrt{n}+sum_{i=1}^{sqrt{n}}sqrt{frac{n}{i^2}})\
    &=&O(sqrt{n}sum_{i=1}^{sqrt{n}}frac{1}{i})\
    &=&O(sqrt{n}log n)
    end{eqnarray*}]

    #include<cstdio>
    typedef long long ll;
    const int N=31622800;
    const ll n=1000000000000000LL;
    int i,j,k,tot,p[N/10],phi[N];bool v[N];ll ans;
    inline ll F(ll n){
      ll ret=0;
      for(ll i=1,j;i<=n;i=j+1){
        j=n/(n/i);
        ret+=n/i*(j-i+1);
      }
      return ret;
    }
    int main(){
      for(phi[1]=1,i=2;i<=n/i;i++){
        if(!v[i])phi[i]=i-1,p[tot++]=i;
        for(j=0;j<tot;j++){
          k=i*p[j];
          if(k>n/k)break;
          v[k]=1;
          if(i%p[j])phi[k]=phi[i]*(p[j]-1);else{
            phi[k]=phi[i]*p[j];
            break;
          }
        }
      }
      for(i=1;i<=n/i;i++)ans+=F(n/i/i)*phi[i];
      return printf("%lld",ans),0;
    }
    

      

  • 相关阅读:
    日志
    JAVA字符串类
    JAVA包
    JAVA面向对象
    JAVA数组
    JAVA循环结构
    JAVA程序调试
    JAVA条件判断
    JAVA算术运算符
    JAVA数据类型
  • 原文地址:https://www.cnblogs.com/clrs97/p/5986601.html
Copyright © 2020-2023  润新知