约数和的公式sum = (p1^0+p1^1+...+p1^m1)*(p2^0+p2^1+....+p2^m2)*....*(pn*0+pn^1+....+pn^mn);
约数和为偶数 即当素因子为奇数时,其最高次幂一定为偶数 当素因子为2时,2^0+2^1+...+2^n一定为奇数
当素因子为3时,3^0+3^1为偶数,3^0+3^1+3^2为奇数
所以本题首先筛选出10^12以内的所有约数和为奇数的数,在根据输入的n找到n以内的约数和为奇数的个数,即可求出n以内约数和为偶数的个数
利用深搜筛选奇数
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
#define i64 long long
i64 prime[500000];
bool p[1000000];
int Count;
i64 odd[1800000];
i64 oddCount;
void makePrime()
{
for(int i = 2;i<1000000;i++)
{
if(p[i]==false)
{
if(i<1000)
{
for(int j = i*i;j<1000000;j+=i)
{
p[j] = true;
}
}
prime[Count++] = i;
}
}
}
void DFS(int dep,i64 cur)
{
odd[oddCount++] = cur;
if(dep>=Count) return;
i64 i,t;
for(i=dep;i<Count;i++)
{
if(i==0)
{
if(cur<=1000000000000/2) DFS(i,cur*2);
else return;
}
else
{
t=(i64)prime[i]*prime[i];
if(cur<=1000000000000/t) DFS(i,cur*t);
else return;
}
}
}
int main()
{
makePrime();
DFS(0,1);
sort(odd,odd+oddCount);
int T;
i64 n;
scanf("%d",&T);
for(int i = 1;i<=T;i++)
{
scanf("%lld",&n);
i64 ans = upper_bound(odd,odd+oddCount,n)-odd;
ans = n - ans;
printf("Case %d: %lld\n",i,ans);
}
return 0;
}