• [SDOI2012] Longge的问题


    欧拉函数

    传送门:$>here<$


    题意:求$sumlimits_{i=1}^{n}gcd(i,n)$

    数据范围:$n leq 2^{32}$


    $Solution$

    设$f(x)$表示$gcd$为$x$的$i$有多少个,这样的话答案就可以被表示为$sumlimits_{i|n}^{n}f(i)*i$

    ($gcd(i,n)$的取值一定是$n$的一个因子)

    因此关键在于如何求出$f(x)$。由定义可得$f(x)=sumlimits_{i=1}^{n}[gcd(i,n)=x]$,等价于$f(x)=sumlimits_{i=1}^{frac{n}{x}}[gcd(dfrac{i}{x},dfrac{n}{x})=1]$。其实也就是$f(x)=sumlimits_{i=1}^{frac{n}{x}}[gcd(i,dfrac{n}{x})=1]$,那么就可以表示为$f(x)=φ(dfrac{n}{x})$

    所以答案也就是$sumlimits_{i|n}^{n}φ(dfrac{n}{i})*i$

    $my code$

    由于$n$较大,肯定不能筛。所以用通项公式$φ(n)=n*prodlimits_{i=1}^{r}dfrac{p_i-1}{p_i}$。由于枚举因子或质因子的复杂度都是$logn$的,所以总的复杂度应该是$O(log^2n)$

    /*By DennyQi 2018*/
    #include <cstdio>
    #include <queue>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    typedef long long ll;
    #define int ll
    const int MAXN = 10010;
    const int MAXM = 20010;
    const int INF = 1061109567;
    inline int Max(const int a, const int b){ return (a > b) ? a : b; }
    inline int Min(const int a, const int b){ return (a < b) ? a : b; }
    inline int read(){
        int x = 0; int w = 1; register char c = getchar();
        for(; c ^ '-' && (c < '0' || c > '9'); c = getchar());
        if(c == '-') w = -1, c = getchar();
        for(; c >= '0' && c <= '9'; c = getchar()) x = (x<<3) + (x<<1) + c - '0'; return x * w;
    }
    int N,ans,tot,Lim;
    inline int phi(int n){
        if(n == 1 || n == 2) return 1;
        int res = n;
        int lim = sqrt(n)+1;
        for(int i = 2; i <= lim && i*i<=n; ++i){
            if(n % i == 0){
                res = res / i * (i-1) ;
            }
            while(n%i==0) n/=i;
        }
        if(n>1) res = res / n * (n-1);
        return res;
    }
    signed main(){
        //freopen(".in","r",stdin);
        N = read();
        Lim = sqrt(N);
        for(int d = 1; d <= Lim; ++d){
            if(N % d == 0){
                if(d * d == N){
                    ans += d * phi(N/d);
                }
                else{
                    ans += d * phi(N/d) + (N/d) * phi(d);
                }
            }
        }
        printf("%lld", ans);
        return 0;
    }
  • 相关阅读:
    Python 模块chardet安装 setup.py
    Windows下Python安装lxml
    intellij idea 如何更改比编辑器文本字体和大小
    [转]C#设计模式(8)-Builder Pattern
    [转]C#设计模式(4)-Simple Factory Pattern
    [转]C#委托的异步调用
    [转]浅谈C#中常见的委托
    C# 线程池
    [转]C#中的委托和事件(续)
    C#(.net)中的DllImport
  • 原文地址:https://www.cnblogs.com/qixingzhi/p/9926168.html
Copyright © 2020-2023  润新知