[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_x\sum_{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);
}
posted @ 2018-09-02 22:56  Rlif  阅读(200)  评论(0编辑  收藏  举报