Sigma Function Input

本文介绍了一种通过素因子分解来快速找出1至n中因子和为偶数的整数个数的方法。利用数学规律避免了直接计算的复杂度,通过去重计算,有效地解决了问题。

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

Description

Sigma function is an interesting function in Number Theory. It is denoted by the Greek letter Sigma (σ). This function actually denotes the sum of all divisors of a number. For example σ(24) = 1+2+3+4+6+8+12+24=60. Sigma of small numbers is easy to find but for large numbers it is very difficult to find in a straight forward way. But mathematicians have discovered a formula to find sigma. If the prime power decomposition of an integer is

Then we can write,

For some n the value of σ(n) is odd and for others it is even. Given a value n, you will have to find how many integers from 1 to n have even value of σ.

Input

Input starts with an integer T (≤ 100), denoting the number of test cases.

Each case starts with a line containing an integer n (1 ≤ n ≤ 1012).

Output

For each case, print the case number and the result.

Sample Input

4

3

10

100

1000

Sample Output

Case 1: 1

Case 2: 5

Case 3: 83

Case 4: 947

题目扩展:


题意:

1—n中,有多少个数的因子和是偶数。

题解:

打表找规律。

素因子分解打表计算前n项和判断奇数偶数可以发现如下规律:

只要是2^x,x^2,2*x^2...只有这种数的因子和是奇数。所以,我们直接去重即可。
但是这些直接去重我们会发现减去的这些值有重复的,所以我们要判断下。

i(代表x||a):0 1 2 3 4 5 6 7 8 9 ......

2^x: 1 2 4 8 16 32 64 128......

a^2:0 1 4 9 16 25 36 49 64 ......

2*a^2:0 2 8 18 32 50 72 ......

我们可以发现2^x里面有的数,x^22*x^2里面都有。

加下划线的字一一对应,加粗的字一一对应。

2^xx^2, x为偶数时二者出现重复。
②2^x
2*x^2,当x为奇数时,二者出现重复。

所以不需要考虑2^x的个数,直接用n减去x^22*x^2的个数就是我们要的结果。

易知:x^2的个数=sqrt(n)2*x^2的个数=sqrt(n/2)

那么为什么会是这样呢?给出推导过程:

n=p1^e1*p2^e2...,f(n)=(p1^(e1+1)-1)/(p1-1))*(p2^(e2+1)-1)/(p2-1))....
(p1^(e1+1)-1/(p1-1))=p1^0+p1^1......+p1^e1;
要使得f(n)为奇数,则(p1^(e1+1)-1)/(p1-1)(pn^(en+1)-1)/(pn-1)都要为奇数;

因为奇数*奇数=奇数,奇数*偶数=偶数;

1)p=2时,2^(e+1)-1,一定为奇数;
2)
p!=2时,则p为奇数(因为p是素因子),则当e为偶数时(p^(e+1)-1)/(p-1)为奇数。Sn=(p^(e+1)-1)/(p-1),相当于首项为1,公比为p的数列求和,p为奇素数,当e为偶数时,为奇数项奇数求和,结果必为奇数。

代码如下:

#include<stdio.h>
#include<iostream>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long
int main()
{
    int t,cc=1;
    cin>>t;
    while(t--)
    {
        ll n;
        cin>>n;
        printf("Case %d: %lld\n",cc++,n-(int)sqrt(n)-(int)sqrt(n/2));
    }

}

转自:https://www.cnblogs.com/Ritchie/p/5299970.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值