D - Sigma Function
D - Sigma Function
题目链接:https://vjudge.net/problem/LightOJ-1336#author=Amove
题目大意:
求和运算是一种有趣的操作,它来源于古希腊字母σ,现在我们来求一个数字的所有因子之和。例如σ(24)=1+2+3+4+6+8+12+24=60.对于小的数字求和是非常的简单,但是对于大数字求和就比较困难了。现在给你一个n,你需要求出有多少个[ 1 , n ]区间内的数字σ是偶数。
注:一个数字的σ指这个数的所有因子之和。
解题思路:
因子和公式:$\left(q 1^{\wedge} 0+q 1^{\wedge} 1 \ldots . . q 1^{\wedge} a 1\right)^{\star}\left(q 2^{\wedge} 0+q 2^{\wedge} 1 \ldots . . q 2^{\wedge} a 2\right)^{\star} \ldots \ldots .^{\star}\left(q n^{\wedge} 0+q n^{\wedge} 1 \ldots . . q n^{\wedge} a n\right)$
由公式可以知道,当因子和为偶数时只需要除了2以外其中任何一项质因子因子的个数为奇数,则因子和为偶数,也就是说只有除了2以外所有的质因子个数都为偶数时,因子和才为奇数,那么质因子都为偶数个,除了2以外的质因子相乘得到的就一定是个平方数。所以,首先遍历2的个数,在遍历平方,需要注意的是得到的平方数不能被2整出,如果能整除就说明相乘的质因子中含有2,也就会造成重复计算。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define debug(a) cout<<#a<<":"<<a<<endl; 4 typedef long long ll; 5 const ll INF=1e9+7; 6 const ll N=1e6+7; 7 const ll mod=1e9+7; 8 ll maxn,minn; 9 ll T,n; 10 11 ll ksm(ll a, ll b){ 12 ll ans=1; 13 while(b){ 14 if(b&1) ans=ans*a; 15 a=a*a; 16 b>>=1; 17 } 18 return ans; 19 } 20 21 int main(){ 22 ll a,b,j,num,t=0; 23 cin>>T; 24 while(T--){ 25 t++; 26 num=0; 27 scanf("%lld",&a); 28 for(ll i=0;i<=60;i++){ 29 b=ksm(2,i); 30 j=3; 31 if(a>=b){ 32 num++; 33 } 34 else{ 35 break; 36 } 37 while(a>=(b*j*j)){ 38 if(j%2!=0){ 39 num++; 40 } 41 j++; 42 } 43 } 44 printf("Case %lld: %lld\n",t,(a-num)); 45 } 46 47 48 return 0; 49 }