想了好久,打表也没看出来规律,看得题解才明白
/*
* 规律:通过打表后发现,在n的范围内,只有2^x 以及 平方数 和 平方数的2倍符合要求。
* 即:2^1, 2^2,... 1*1, 2*2,... 2*1*1, 2*2*2, 2*3*3... 等等,故只要去重就可以了
* url: http://uva.onlinejudge.org/index.php?option=onlinejudge&page=show_problem&problem=2390
* stratege: 规律,对数
* Author: Johnsondu
*/
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
#define LL long long
LL n, t1, t2, t3, t4, t5, t6 ;
int main ()
{
int tcase, cas = 1 ;
scanf ("%d", &tcase) ;
while (tcase --)
{
scanf ("%lld", &n) ;
if (n == 1)
{
printf ("Case %d: 0\n", cas++) ;
continue ;
}
t1 = (LL)sqrt (n*1.0) ; //一共有t1^2 < n, 故有t1 个
t2 = (LL)(log(n*1.0) / log(2.0)) ; // 2^t2 内, 有t2个
t3 = ((LL)(log(n*1.0) / log(2.0)) - 1) / 2 + 1 ; // 2*x*x与2^t2中,与2^3, 2^7,...,重复
t4 = (LL)sqrt (n/2.0) ; // 2*x*x一共有t4个
t5 = (LL) (log(t1*1.0)/log(2.0)) ; //t1中x*x 与 2^t2重复的有t5个
printf ("Case %d: %lld\n", cas++, n - (t1 - t5 + t2 + t4 - t3)) ;
}
return 0 ;
}