zoukankan      html  css  js  c++  java
  • 【洛谷 P2303】 [SDOi2012]Longge的问题 (欧拉函数)

    题目链接
    题意:求(sum_{i=1}^{n}gcd(i,n))

    首先可以肯定,(gcd(i,n)|n)

    所以设(t(x))表示(gcd(i,n)=x)(i)的个数。

    那么答案很显然就是(sum_{d|n}t(d)*d)

    那么(t(x))怎么求呢。

    [t(x)=sum_{i=1}^{n}[gcd(i,n)=x] ]

    因为若(gcd(x,y)=1),则有(gcd(xk,yk)=k)
    所以

    [t(x)=sum_{i=1}^{n}[gcd(i,n)=x]=sum_{i=1}^{lfloorfrac{n}{x} floor}[gcd(i,lfloorfrac{n}{x} floor)=1]=phi(lfloorfrac{n}{x} floor) ]

    所以最终答案就是(sum_{d|n}[phi(lfloorfrac{n}{d} floor)*d])

    我们可以在(O(sqrt n))的时间复杂度内求出(n)的所有约数,约数个数是(log n)级别的,求(phi)(O(sqrt n))的时间复杂度,所以总时间复杂度(O(log nsqrt n))

    #include <cstdio>
    #include <cmath>
    using namespace std;
    typedef long long ll;
    ll n;
    ll phi(ll x){
        int s = sqrt(x); ll ans = x;
        for(int i = 2; i <= s && x != 1; ++i)
           if(!(x % i)){
             ans = ans / i * (i - 1);
             while(!(x % i))
               x /= i;
           }
        if(x != 1) ans = ans / x * (x - 1);
        return ans;
    }
    int main(){
        scanf("%lld", &n);
        int i; ll ans = 0;
        for(i = 1; (ll)i * i < n; ++i)
           if(!(n % i))
             ans += phi(n / i) * i + (n / i) * phi(i);
        if(i * i == n) ans += phi(i) * i;
        printf("%lld
    ", ans);
        return 0;
    } 
    
    
  • 相关阅读:
    3. 尾缀
    Cocos工程命名规则整理(node部分)
    3.1-3.3 HBase Shell创建表
    2.11-2.12 HBase的数据迁移常见方式
    2.8-2.10 HBase集成MapReduce
    2.7 HBase架构深入剖析
    2.3-2.6 HBase java API
    2.1-2.2 HBase数据存储
    1.6-1.8 HBase表的物理模型
    1.4-1.5 HBase部署及基本使用
  • 原文地址:https://www.cnblogs.com/Qihoo360/p/9777286.html
Copyright © 2011-2022 走看看