#枚举 我们发现,计算 $x$ 的所有约数之和非常简单,但是已知约数之和为 $y$,求出最小的 $x$ 非常复杂,答案也不满足单调性。因此,考虑预处理 $1\sim 10^7$ 当中所有数的约数之和。 找到 $x$ 的所有约数是 $\mathcal O(\sqrt x)$ 的,但是这题 $x\le 10^7$。考虑换种方法,不是枚举一个数的因数有哪些,而是枚举一个数的倍数有哪些。准确来说,就是枚举因数 $i$,然后将 $i$ 的所有倍数 $ki$ 的函数值全部的加上 $i$。 这样子时间复杂度大约为 $\mathcal O(n\log_2 n)$,可以极限卡过。 ```cpp #include <iostream> #pragma GCC optimize(2) using namespace std; const int kMaxN = 1e7 + 5; int f[kMaxN], a[kMaxN], t, x; int main() { ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); // 预处理 1 的倍数,常数优化 fill(f, f + kMaxN, 1); // 将所有数的倍数加上这个数 for (int i = 2; i <= 1e7; i++) { for (int j = i; j <= 1e7; j += i) { f[j] += i; } } // 记录最小答案 for (int i = 1; i <= 1e7; i++) { if (f[i] <= 1e7 && !a[f[i]]) { a[f[i]] = i; } } // 询问 for (cin >> t; t; t--) { cin >> x; cout << (a[x] ? a[x] : -1) << '\n'; } return 0; } ```