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

探讨了如何通过数论中的约数之和函数σ(n)来解决LightOJ1336题目,分析了约数之和为偶数的条件,并给出了高效算法实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

题意:

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

n=p1a1×p2a2×...×pkak,其中p1,p2,...,pk是n的素因子,ai≥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=p1a1×p2a2×...×pkakp1,p2,...,pknai0

约数之和:约数之和::

σ(n)=p1a1+1−1p1−1×p2a2+1−1p2−1×...×pkak+1−1pk−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}σ(n)=p11p1a1+11×p21p2a2+11×...×pk1pkak+11

=(1+p11+p12+...+p1a1)×(1+p21+p22+...+p2a2)×...×(1+pk1+pk2+...+pkak)=(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+p11+p12+...+p1a1)×(1+p21+p22+...+p2a2)×...×(1+pk1+pk2+...+pkak)

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

输入:

T组测试数据,T组测试数据,T

每组包括一个正整数n。每组包括一个正整数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≤1012T≤100,1≤n≤10^{12}T1001n1012


分析:

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

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

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

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

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

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

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

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

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

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

需满足对n的任意质因子pi,1+pi1+pi2+...+piai为奇数。需满足对n的任意质因子p_i,1+p_i^1+p_i^2+...+p_i^{a_i}为奇数。npi1+pi1+pi2+...+piai

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

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

②、对于其他素因子pi,要使1+pi1+pi2+...+piai为奇数,必有pi1+pi2+...+piai为偶数,②、对于其他素因子p_i,要使1+p_i^1+p_i^2+...+p_i^{a_i}为奇数,必有p_i^1+p_i^2+...+p_i^{a_i}为偶数,pi使1+pi1+pi2+...+piaipi1+pi2+...+piai

首先pik必为奇数,偶数个奇数相加为偶数,故ai必为偶数。\qquad首先p_i^k必为奇数,偶数个奇数相加为偶数,故a_i必为偶数。pikai

也就是说,对于任意的pi≠2,1+pi1+pi2+...+piai为奇数当且仅当ai为偶数。\qquad也就是说,对于任意的p_i≠2,1+p_i^1+p_i^2+...+p_i^{a_i}为奇数当且仅当a_i为偶数。pi=21+pi1+pi2+...+piaiai

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

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

由于ai为偶数,我们记ai=2ai′,则n=2k×(p1a1′)2×(p2a2′)2×...×(pkak′)2由于a_i为偶数,我们记a_i=2a_i',则n=2^k×(p_1^{a_1'})^2×(p_2^{a_2'})^2×...×(p_k^{a_k'})^2aiai=2ain=2k×(p1a1)2×(p2a2)2×...×(pkak)2

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

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

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

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

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

注意:我们最后要输出n−cnt,n是long long级别的,最后要以长整型格式输出。我们最后要输出n-cnt,n是long\ long级别的,最后要以长整型格式输出。ncntnlong 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值