数论(约数之和) - Sigma Function - LightOJ 1336

数论(约数之和) - Sigma Function - LightOJ 1336

题意:

n 根据算数基本定理,对任意正整数n,可分解为:

n = p 1 a 1 × p 2 a 2 × . . . × p k a k p 1 , p 2 , . . . , p k n a i 0 n=p_1^{a_1}×p_2^{a_2}×...×p_k^{a_k},其中p_1,p_2,...,p_k是n的素因子,a_i≥0。

: 约数之和:

σ ( n ) = p 1 a 1 + 1 1 p 1 1 × p 2 a 2 + 1 1 p 2 1 × . . . × p k a k + 1 1 p k 1 σ(n)=\frac{p_1^{a_1+1}-1}{p_1-1}×\frac{p_2^{a_2+1}-1}{p_2-1}×...×\frac{p_k^{a_k+1}-1}{p_k-1}

= ( 1 + p 1 1 + p 1 2 + . . . + p 1 a 1 ) × ( 1 + p 2 1 + p 2 2 + . . . + p 2 a 2 ) × . . . × ( 1 + p k 1 + p k 2 + . . . + p k a k ) =(1+p_1^1+p_1^2+...+p_1^{a_1})×(1+p_2^1+p_2^2+...+p_2^{a_2})×...×(1+p_k^1+p_k^2+...+p_k^{a_k})

[ 1 , n ] i i σ ( i ) 计算区间[1,n]内,有多少个正整数i,满足i的约数之和σ(i)是偶数。

输入:

T T组测试数据,

n 每组包括一个正整数n。

输出:

一个正整数,表示答案。

Sample Input

4
3
10
100
1000

Sample Output

Case 1: 1
Case 2: 5
Case 3: 83
Case 4: 947

数据范围:

T 100 1 n 1 0 12 T≤100,1≤n≤10^{12}


分析:

n O ( n ) 对于每个正整数n,求约数之和的时间复杂度为O(\sqrt{n}),

[ 1 , n ] 若对[1,n]内的每个数都暴力统计一次,显然是不能够的。

σ ( n ) 我们考虑从σ(n)的特征入手。

σ ( n ) \sigma(n)是乘积的形式,我们要判断其奇偶性,我们知道:

× = ①、偶数×偶数=偶数

× = ②、偶数×奇数=偶数

× = ③、奇数×奇数=奇数

σ ( n ) 由此可见,\sigma(n)为奇数的可能性是比较少的。

[ 1 , n ] c n t n c n t 所以,我们可以求出[1,n]内,约数之和为奇数的数的个数cnt,再用总数n-cnt,得到答案。

下探究σ(n)何时为奇数:

n p i 1 + p i 1 + p i 2 + . . . + p i a i 需满足对n的任意质因子p_i,1+p_i^1+p_i^2+...+p_i^{a_i}为奇数。

2 在所有的素数中,仅2为偶数,其他素数均为奇数。

n 2 1 + 2 1 + 2 2 + . . . + 2 a 1 ①、当n有素因子2时,1+2^1+2^2+...+2^{a_1}恒为奇数。

p i 使 1 + p i 1 + p i 2 + . . . + p i a i p i 1 + p i 2 + . . . + p i a i ②、对于其他素因子p_i,要使1+p_i^1+p_i^2+...+p_i^{a_i}为奇数,必有p_i^1+p_i^2+...+p_i^{a_i}为偶数,

p i k a i \qquad首先p_i^k必为奇数,偶数个奇数相加为偶数,故a_i必为偶数。

p i 2 1 + p i 1 + p i 2 + . . . + p i a i a i \qquad也就是说,对于任意的p_i≠2,1+p_i^1+p_i^2+...+p_i^{a_i}为奇数当且仅当a_i为偶数。

σ ( n ) n ( 2 ) a i 总结:\sigma(n)为奇数,当且仅当n的所有素因子(除了2以外)的指数a_i均为偶数,

2 2 \qquad\quad若存在素因子2,对因子2的指数无要求。

a i a i = 2 a i n = 2 k × ( p 1 a 1 ) 2 × ( p 2 a 2 ) 2 × . . . × ( p k a k ) 2 由于a_i为偶数,我们记a_i=2a_i',则n=2^k×(p_1^{a_1'})^2×(p_2^{a_2'})^2×...×(p_k^{a_k'})^2

k ( p 1 a 1 ) 2 × ( p 2 a 2 ) 2 × . . . × ( p k a k ) 2 其中k为任意非负整数,我们发现,(p_1^{a_1'})^2×(p_2^{a_2'})^2×...×(p_k^{a_k'})^2是一个完全平方数,

k n k n 当k为偶数时,n就是一个完全平方数;当k为奇数时,n是一个完全平方数的两倍。

σ ( n ) n 综上:\sigma(n)为奇数,当且仅当n是一个完全平方数或是一个完全平方数的两倍。

[ 1 , n ] 2 c n t n c n t 因此,我们仅需统计出[1,n]以内,所有是完全平方数和完全平方数的2倍的数的个数,即为cnt。答案为n-cnt。

2 可以证明,一个完全平方数的2倍一定不是完全平方数,因此统计这两种数不会产生冲突。这里可以简化代码。

注意: n c n t n l o n g   l o n g 我们最后要输出n-cnt,n是long\ long级别的,最后要以长整型格式输出。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

#define ll long long

using namespace std;

int T;
ll n;

int main()
{
    cin>>T;
    for(int t=1;t<=T;t++)
    {
        cin>>n;
        int cnt=0;
        for(ll i=1;i*i<=n;i++,cnt++)
            if(2*i*i<=n) cnt++;
        printf("Case %d: %lld\n",t,n-cnt);
    }
    
    return 0;
}

猜你喜欢

转载自blog.csdn.net/njuptACMcxk/article/details/107735148