Sigma Function
题目
给定一个n<=1e12,求在n之前的正整数,有多少个约数之和为偶数。
分析
我在题目的公式上看了半天推不出结论来。此题十分适合打表观察规律,所以可以打表看看。
打表结果:
1 : odd 2 : odd 3 : even 4 : odd 5 : even 6 : even 7 : even 8 : odd 9 : odd 10 : even 11 : even 12 : even 13 : even 14 : even 15 : even 16 : odd 17 : even 18 : odd 19 : even 20 : even 21 : even 22 : even 23 : even 24 : even 25 : odd 26 : even 27 : even 28 : even 29 : even 30 : even 31 : even 32 : odd 33 : even 34 : even 35 : even 36 : odd 37 : even 38 : even 39 : even 40 : even 41 : even 42 : even 43 : even 44 : even 45 : even 46 : even 47 : even 48 : even 49 : odd 50 : odd 51 : even 52 : even 53 : even 54 : even 55 : even 56 : even
可以得出规律:约数之和的数,要么是平方数,要么除以2之后是个平方数.所以我们可以把满足这条件的统计出来,就是约数之和为奇数的个数。然后n-约数之和为奇数的个数就可以了。
AC代码
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 1e6+10;
typedef long long ll;
int T;
ll fun(ll x){
ll res = 0;
for(int i = 1;i<=x;i++){
if(x%i == 0) res += i;
}
return res%2;
}
int main(){
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
// for(int i = 1;i<=1000;i++){ //打表
// cout<<i<<" : ";
// if(fun(i)) cout<<"odd"<<endl;
// else cout<<"even"<<endl;
// }
cin>>T;
int kase = 0;
while(T--){
ll n,odd = 0;
scanf("%lld",&n);
for(ll i = 1;i*i<=n;i++){
odd++;
if(2*i*i<=n){
odd++;
}
}
printf("Case %d: %lld\n",++kase,n-odd);
}
return 0;
} 
京公网安备 11010502036488号