参考博客:https://blog.csdn.net/guagua_de_xiaohai/article/details/81293295
题目链接:https://cn.vjudge.net/problem/LightOJ-1336
题意:求 1—n 中,有多少个数的因子和是偶数。
案例分析:
4 (4个测试案例)
3:(1 2 3 4 )1
10:(1 2 3 4 5 6 7 8 9 10)5
第一种情况:奇 素数(除2以外所有素数都是奇数,1既不是素数也不是合数)
第二种情况:偶 其它因子全是一偶一奇
9 1 9 3 (只算一个3)
打表找规律。
素因子分解打表计算前n项和判断奇数偶数可以发现如下规律:
只要是2^x,a^2,2*a^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里面有的数,a^2和2*a^2里面都有。
加下划线的字一一对应,加粗的字一一对应。
①2^x和a^2, 当x为偶数时二者出现重复。
②2^x和2*a^2,当x为奇数时,二者出现重复。
所以不需要考虑2^x的个数,直接用n减去a^2和2*a^2的个数就是我们要的结果。
易知:a^2的个数=sqrt(n),2*a^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)为奇数。
经转化我们可以发现,2^6=8^2,2^11=2*32^2。也就是平方数和2倍的平方数。
则需要统计1到n中的平方数个数和2倍的平方数的个数,得到的为1到n中f(n)为奇数的个数。
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
int main(){
int t,k=1;
cin>>t;
while(t--){
long long n,a,b;
cin>>n;
a=sqrt(n);
b=sqrt(n/2);
printf("Case %d: %lld\n",k,n-a-b);
//不能直接这样n-sqrt(n)-sqrt(n/2)
k++;
}
return 0;
}