P4446 [AHOI2018初中组] 根式化简
算法
素数筛。
思路
有一个结论,如果将一个数 \(x\) 的 \(x^{\frac{1}{4}}\) 内的素因子筛掉,那么剩下的数一定是一个完全立方数或者不能被开立方。
如何证明呢?
采用反证法,若存在因子 \(p > x^{\frac{1}{4}}\),使得剩下的 \(x\) 能被表示为 \(p^3 \times a\),那 \(a\) 一定大于 \(x^{\frac{1}{4}}\)(因为之前已将 \(\le x^{\frac{1}{4}}\) 的因子筛完了),所以 \(p^3 \times a > x\),与命题矛盾,得证。
接下来考虑实现。
因为 \(\sqrt[4]{10^{18}} < 32000\),所以我们可以先预处理出 32000 内的素数。
再将 \(\le x^{\frac{1}{4}}\) 的素因子筛去,如果有 3 次方的记得加在答案里。
最后处理完,判断剩下的 \(x\) 是否是完全立方数即可(可以预处理一个 \(x^{\frac{1}{3}}\) 的数组,最后进行二分查找)。
#include "iostream"
#include "cmath"
using namespace std;
#define int long long
const int N = 3.2e4 + 1;
int prime[N], cnt = 0;
bool is_prime[N];
inline void init_prime() {
for (int i = 2; i <= 3.2e4; ++i) {
if (!is_prime[i])
prime[++cnt] = i;
for (int j = 1; j <= cnt and i * prime[j] <= 3.2e4; ++j) {
is_prime[i * prime[j]] = 1;
if (!(i % prime[j]))
break;
}
}
return;
}
inline void calculate(int x) {
int t = sqrt(sqrt(x)), ans = 1;
for (int i = 1; i <= cnt and prime[i] <= t; ++i) {
int tot = 0;
while (!(x % prime[i])) {
x /= prime[i], ++tot;
if (tot == 3)
ans *= prime[i], tot = 0;
}
}
int f = round(pow(x, 1.0 / 3));
if (f * f * f == x)
ans *= f;
cout << ans << '\n';
return;
}
int n;
inline void solve() {
init_prime();
cin >> n;
for (int i = 1; i <= n; ++i) {
int x;
cin >> x;
calculate(x);
}
return;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
solve();
return 0;
}
分类:
题目总结
, 题目总结 / 2024. 10~12月
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现