题解:

考察点: 数学,打表找规律

易错点:

注意最好把都开成long long类型,因为在计算的过程中有可能会爆

解法:打表找规律

这题第一眼看上去并没有什么神奇的数学结论可以一眼秒掉,但数据范围又这门大,很显然可以通过打表来找规律。于是对以内的小数据进行暴力

#include "bits/stdc++.h"
using namespace std;
int main()
{
    for(int i=1;i<=100;i++){
        int sum=0;
        for(int j=1;j<=i;j++){
            sum+=i/j;
        }
        if(sum%2==0){
            if(i%100==0) printf("%d\n",i);
            else printf("%d ",i);
        }
    }
    printf("\n");
    return 0;
}

整理结果后有如下结果

4 5 6 7 8 
16 17 18 19 20 21 22 23 24 
36 37 38 39 40 41 42 43 44 45 46 47 48 
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 
100

很显然可以从上表中观察出来,当为偶数时,位于区间内数全为满足要求的怪数。

有了这个结论之后,对于整数,就可以快速统计出内的怪数个数。设,则对进行分类讨论。如果是奇数,则说明从一直到之后不可能再存在怪数。而前面的怪数个数。而如果是偶数,则说明后面从还存在怪数,故结果应该是最后还应该加上。最后的集过应该为区间内的个数,减去区间内的个数。

#include "bits/stdc++.h"
using namespace std;
typedef long long LL;
LL a,b;
LL solve(LL x){
    if(x<0) return 0;
    if(x==0) return 1;
    LL v=sqrt(x),s=0;
    if(v%2){
        return v*(v+1)/2;
    }else{
        LL t=v-1;
        s=t*(t+1)/2;
        s+=x-v*v+1;
    }
    return s;
}
int main()
{
    scanf("%lld%lld",&a,&b);
    printf("%lld\n",solve(b)-solve(a-1));
    return 0;
}