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 }

 

posted @ 2020-03-02 17:43  yya雨  阅读(170)  评论(0编辑  收藏  举报