[luogu p7464] [CERC2018] The Silence of the Lamps
洛谷 P7464 [CERC2018] The Silence of the Lamps
\(\mathtt{Link}\)
P7464 [CERC2018] The Silence of the Lamps - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
\(\mathtt{Description}\)
\(T\) 组多测。
给定一个数 \(n\),求满足以下条件的三元正整数组 \((i, j, k)\) 的数量:
-
\(0 < i < j < k \le n\)
-
\(i \times j \times k \le n\)
\(\mathtt{Data} \text{ } \mathtt{Range} \text{ } \mathtt{\&} \text{ } \mathtt{Restrictions}\)
- \(1 \le T \le 10^5\)
- \(1 \le n \le 10^6\)
\(\mathtt{Solution}\)
为什么不 % 1e9 + 7
发现本题中的三元组合法性满足包含关系,举个例子:\(n = 8\) 时合法的三元组一定包含 \(n = 5\) 时合法的三元组。
因此首先考虑将询问离线下来,对每个 \(g\) 求出 \(i \times j \times k = g\) 的三元组数量,进行前缀和,直接回答询问。
复杂度无法承受。考虑逆向思维,暴力枚举 \(i, j, k\),采用桶计数的思想,将 \(i \times j \times k\) 对应的桶自增1。
然后这个题就做完了。
\(\mathtt{Time} \text{ } \mathtt{Complexity}\)
不会求,感觉大概 \(\operatorname{O}(n \log ^3n)\)?(嘴的)
\(\mathtt{Code}\)
/*
* @Author: crab-in-the-northeast
* @Date: 2022-05-04 12:34:28
* @Last Modified by: crab-in-the-northeast
* @Last Modified time: 2022-05-04 12:46:55
*/
#include <iostream>
#include <cstdio>
#include <cmath>
inline int read() {
int x = 0;
bool flag = true;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
flag = false;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + ch - '0';
ch = getchar();
}
if(flag) return x;
return ~(x - 1);
}
const int maxn = 1e6 + 5;
int a[maxn];
int main() {
int T = read();
for (int i = 1; i < cbrt(maxn); ++i)
for (int j = i + 1; j <= maxn / i; ++j)
for (int k = j + 1; k <= maxn / i / j; ++k)
++a[i * j * k];
for (int i = 2; i <= maxn; ++i)
a[i] += a[i - 1];
while (T--) {
int x = read();
printf("%d\n", a[x]);
}
return 0;
}