LightOJ1336 Sigma Function —— 质因子分解、约数和为偶数
题目链接:https://vjudge.net/problem/LightOJ-1336
Time Limit: 2 second(s) | Memory Limit: 32 MB |
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 |
Output for Sample Input |
4 3 10 100 1000 |
Case 1: 1 Case 2: 5 Case 3: 83 Case 4: 947 |
题意:
求1到n(n<=1e12)内,有多少个数的约数和为偶数。
题解:
1.将一个数n进行质因子分解,得到 pi 和 ai,其中pi为第i个质因子,ai为第i个质因子的个数,
那么这个数的约数和:f(n) = (1+2^1+2^2……2^a1)*(1+3^1+3^2……3^a2)……*(1+pi^1+pi^2……pi^ai)*……
解释:从每一个括号中挑选一个数出来相乘,就得到一个约数。在根据组合数的思想,总的就得到所有约数的和。
2.可知:偶数可以是偶数乘以偶数,也可以是奇数乘以偶数;而奇数只能是奇数乘以奇数。所以,统计奇数要比统计偶数方便,所以总体思想就是用总的个数减去约数和为奇数的个数。
3.那么,要使 f(n) 为奇数,必须满足每个括号中的数之和为奇数。可知,当pi = 2时,括号里的数必定为奇数。因为2的正数次方均为偶数,再加上一个1,就为奇数。所以:
3.1 当n不含有2这个质因子时:每个括号内ai必须为偶数,当ai为偶数就说明了括号内有 ai+1个奇数相加,和为奇数。因此,当每个质因子的个数ai均为偶数时,n可以表示为 n = x^2,即表明当n为一个平方数时,f(n)为奇数。
3.2 当n含有2这个质因子时:可知对于2来说,无论它的个数为多少,对应括号里的和都为奇数,那么只要同时满足其他括号里的数之和都为奇数,即满足3.1的要求,那么f(n)为奇数。此时 n = 2*x^2。(注:当n = 2*2*2*x^2时, n = 2*(2*x)^2,即同样满足 2*x^2的通项公式)
3.3 综上,当 n = x^2 或者 n = 2*x^2时, f(n)为奇数。所以在n之内,有sqrt(n) + sqrt(n/2) 个数的约数和为奇数。
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <cmath> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 using namespace std; 13 typedef long long LL; 14 const int INF = 2e9; 15 const LL LNF = 9e18; 16 const int mod = 1e9+7; 17 const int MAXM = 1e5+10; 18 const int MAXN = 5e5+10; 19 20 int main() 21 { 22 int T, kase = 0; 23 scanf("%d", &T); 24 while(T--) 25 { 26 LL n; 27 scanf("%lld",&n); 28 LL ans = n - (LL)sqrt(n) - (LL)sqrt(n/2); 29 printf("Case %d: %lld\n", ++kase,ans); 30 } 31 }