题目链接
分析
为防止格式走样,先贴一张图
满足ab|x的(a,b)a,b)个数为 f(x),求 f(1)+f(2)+...+f(n) 3
借鉴 Uva11526—H(a,b)n),想到了一种 O(n4 ) 复杂度的解法,可惜超时,考虑下面序列的 计数:
n/(1×1)、n/(1×2)、...、n/(1×n),共 H(n)个 n/(2×1)、n/(2×2)、...、n/(2× n2 ),共 H(n/2)个
⋮
n/(n×1),共 H(n/n)个
实际只需要求 H(n)、H(n/2)、...、H(n/ √n ),后面的用分段统计
计算代价为: √n+√n/2+...+√n/√n=√n×(1+ 1 + 1 +...+ 1 )
可以证明 √n≤(1+ 1 + 1 +...+ 1 )<2√n √2√3 √n
现在换一个思路,直接求 f(x) :满足 ab|x 的(a,b)a,b)个数等价于求 abc=x 的(a,b)a,b,c)个数, 因此 f(1)+f(2)+...+f(n)等于求abc≤n的(a,b)a,b,c)个数。
不妨假定 a≤b≤c,再在计数时考虑 a,b,c 的排列,可见 a≤√3 n , a≤b≤√n/a , b≤c≤n 。
111 3 因此 (1+ + +...+ )=O(√√n) , √n+√n/2+...+√n/√n=O(n4 )
√2 √3 √√n
在 n= 1011 时,计算代价在 108 以上,因此超时。
ab
可以写出一个两重循环,代价为 √n+√n/2+...+√n/√3 n=√n×(1+ 1 + 1 +...+ 1 )
√2 √3 √√n
362 3
√2 √3 √3√n
复杂度为 √n×O( √n)=O(√n×√n)=O(n ) √
在 n= 1011 时,计算代价在 107 ,不超时。 最后,再来考虑具体计数的逻辑:
10 ,a<b 时:若 b=c,有 3 种排列; 若 b<c,有 6 种排列,c 有
为 6(n−b)+3 ab
n −b 个取值,总共 ab
20 ,a=b 时:若 b=c,有 1 种排列; 若 b<c,有 3 种排列,总计数为 3( n −b)+1
AC代码
#include <iostream>
#include <cmath>
using namespace std;
int main() {
long long n; int kase = 0;
while (cin >> n) {
long long ans = 0;
for (long long i=pow(n+.5l, 1.l/3); i>0; --i) for (long long j=sqrt(.5l+n/i); j>=i; --j)
ans += i<j ? 6*(n/i/j-j)+3 : 3*(n/i/j-j)+1;
cout << "Case " << ++kase << ": " << ans << endl;
}
return 0;
}