题目大意:
给定一个long long 型的数 n,找到一共有多少对a,b,使比n小的某一个数的是a*b的倍数
这样我们可以理解为
存在a*b*c <= n,令 a <= b <= c ,当a=b=c时,存在一组 , a=b时,存在3组,均不相同,那么存在6组
且a <= pow(n , 1.0/3) b <= pow(n/a , 1.0/2)
那么复杂度就缩小为 a*b了
注意过程中均为long long 型的数返回,否则数据大了会出现误差
#include <cstdio> #include <cstring> #include <cmath> using namespace std; typedef long long LL; LL getPowThird(LL x) { LL a = pow(x , 1.0 / 3); while(a*a*a <= x) a++; while(a*a*a > x) a--; return a; } LL getPowBinary(LL x) { LL a = pow(x , 1.0 / 2); while(a*a <= x) a++; while(a*a > x) a--; return a; } int main() { // freopen("test.in","rb",stdin); LL n ; int cas = 0; while(scanf("%I64d",&n)!=EOF){ LL ans = 0; LL a = getPowThird(n); LL np; for(int i = 1; i <= a ;i++){ np = n / i; LL b = getPowBinary(np); for(int j = i ; j <= b ;j++){ LL t = np/j; if(i == j){ ans += (LL)3 * (t-j) + 1; } else ans += (LL)6* (t-j) + 3; } } printf("Case %d: %I64d ", ++cas , ans); } return 0; }