zoukankan      html  css  js  c++  java
  • [SDOi2012]Longge的问题 (数论)

    Luogu2303 [SDOi2012]Longge的问题

    题目

    题目背景
    SDOi2012

    题目描述
    Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题。现在问题来了:给定一个整数N,你需要求出

    [sum_{i=1}^{n}GCD(i,n) ]

    输入输出格式
    输入格式:
    一个整数,为N。

    输出格式:
    一个整数,为所求的答案。

    输入输出样例
    输入样例#1: 复制
    6
    输出样例#1: 复制
    15
    说明
    对于60%的数据,(0<N<=2^{16})

    对于100%的数据,(0<N<=2^{32})

    题解

    显然直接枚举会超时.
    但有60分可得.
    考虑换个枚举点.
    可能成为GCD(i,n)的数就是n的因子.
    (sqrt n)的枚举n的因子.
    然后求
    (sum_xsum_{i=1}^nGCD(i,n)== x)
    前半部枚举,考虑如何处理后半部分.

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

    [sum_{i=1}^{n/x} GCD(i,n/x) == 1 ]

    看出这就是求(phi {x})
    然后直接求就好.
    时间复杂度:(O(因子个数*sqrt n))
    CODE:

    // luogu-judger-enable-o2
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #define ll long long 
    
    ll phi(ll x)  
    {  
        ll ans = x,qwq = sqrt(x);  
        for(ll i = 2;i <= qwq;++i)  
            if(x % i == 0)  
            {  
                ans = ans - ans / i;  
                while(x % i == 0)  x /= i;   
            }  
        if(x > 1)  ans = ans - ans / x;
        return ans;  
    }  
    
    int main() {
        ll n;
        scanf("%lld",&n);
        ll m = sqrt(n);
        ll ans = 0;
        for(int i = 1;i <= m;++ i) {
            if(n % i == 0) ans += i * phi(n / i) + n / i * phi(i);
        }
        if(m * m == n) ans -= m * phi(m);
        printf("%lld",ans);
    }
    
  • 相关阅读:
    程序员新年要实现的10个愿望
    编写超级可读代码的15个最佳实践
    LeetCode 最大子序和
    LeetCode 最大正方形
    LeetCode 买卖股票的最佳时机 II
    LeetCode 买卖股票的最佳时机
    B树和B+树
    SQL的几种连接
    LeetCode 无重复字符的最长子串
    LeetCode 翻转字符串里的单词
  • 原文地址:https://www.cnblogs.com/tpgzy/p/9575879.html
Copyright © 2011-2022 走看看