把 M=m1^m2 和每个 Si 都分解质因数,整除性只看 m1 的质数;t 秒后 Si^t 对质数 p 有 cnt·t 个,逐个质数取 ceil(e/cnt) 的最大值即为该细胞的等待时间。
OJ: roj
题目 ID: 3570
难度:普及+/提高-
标签:
创建: 2026-10-02 08:13
更新: 2026-10-10 11:30
形式化题目
给定
若不存在这样的
数据范围:
正解
思路
把"细胞个数能被
朴素想法:
关键观察 1:整除性只由质因数指数决定。
关键观察 2:只关心
对所有质数取最大值,就是这种细胞最早的实验时间。统计
合并成答案:对每个
用样例 2 验证:
代码
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-10-10 11:30
* update_at: 2026-10-10 11:30
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
int m1, m2;
// 把 m1 分解质因数,返回各质数及指数
vector<pair<int, int> > factorize(int x) {
vector<pair<int, int> > res;
for (int d = 2; d * d <= x; d++) {
if (x % d == 0) {
int e = 0;
while (x % d == 0) { x /= d; e++; }
res.push_back(make_pair(d, e));
}
}
if (x > 1) res.push_back(make_pair(x, 1));
return res;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m1 >> m2;
vector<pair<int, int> > fac = factorize(m1);
int ans = -1;
for (int i = 0; i < n; i++) {
int s;
cin >> s;
int steps = 0;
bool ok = true;
for (size_t fi = 0; fi < fac.size(); fi++) {
int p = fac[fi].first;
int e = fac[fi].second * m2; // 需求指数
int cnt = 0;
while (s % p == 0) { s /= p; cnt++; }
if (cnt == 0) { ok = false; break; }
int t = (e + cnt - 1) / cnt;
if (t > steps) steps = t;
}
if (ok && (ans < 0 || steps < ans)) ans = steps;
}
cout << ans << "\n";
return 0;
}#!/usr/bin/env python3
# Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
# rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
# rainboy的学习导航网站: https://idx.roj.ac.cn
# create_at: 2026-10-02 08:13
# update_at: 2026-10-02 08:13
import sys
from collections.abc import Iterator
def factorize(m1: int) -> dict[int, int]:
"""把 m1 分解质因数,返回 {质数: 指数};m1 ≤ 30000,试除到 √m1 即可。"""
factors: dict[int, int] = {}
d = 2
while d * d <= m1:
while m1 % d == 0:
factors[d] = factors.get(d, 0) + 1
m1 //= d
d += 1
if m1 > 1: # 剩下的大于 1 的部分本身就是一个质数
factors[m1] = factors.get(m1, 0) + 1
return factors
def seconds_needed(s: int, need: dict[int, int]) -> int:
"""细胞 s 每秒乘以自己,至少多少秒后 s^t 含有 need 里每个质数的全部指数。
返回 -1 表示 s 缺某个质数,无论分裂多久都凑不齐。
只需统计 s 中 m1 的那些质数的指数,其余大质因子与整除性无关。
"""
steps = 0
for p, e in need.items():
cnt = 0 # s 中质数 p 的指数
while s % p == 0:
s //= p
cnt += 1
if cnt == 0: # s 里没有 p,s^t 永远不含 p
return -1
# t 秒后 s^t 有 cnt*t 个 p,要求 cnt*t ≥ e,即 t = ceil(e / cnt)
steps = max(steps, -(-e // cnt))
return steps
def solve() -> None:
data = iter(map(int, sys.stdin.buffer.read().split()))
n = next(data)
m1, m2 = next(data), next(data)
# M = m1^m2,每个质数的总需求指数 = m1 中的指数 × m2
need = {p: e * m2 for p, e in factorize(m1).items()}
ans = -1
for _ in range(n):
s = next(data)
steps = seconds_needed(s, need)
if steps >= 0 and (ans < 0 or steps < ans):
ans = steps # 所有能凑齐的细胞里取最早开始的时间
print(ans)
if __name__ == "__main__":
solve()复杂度
- 分解
:试除到 , 。 - 每个
:对 的每个质数 做除法统计指数。 的不同质因子最多 个( 略超,故至多 个, ),每个质数至多除 次,单个 约 ;总计 ,远低于限时。
图示解析
从细胞个数到质数指数
以样例 2 的
| 能否被 |
||||
|---|---|---|---|---|
| 1 | 否( |
|||
| 2 | 是(答案) | |||
| 3 | 是(但更晚) |
总结
- 把"均分
个试管"写成整除条件 ,用质因数指数逐项比较,避免直接计算 这样的大数。 试除分解;对每个 只统计 的那些质数的指数,缺质数即无解,否则答案为 。 - 全体细胞取最小值;复杂度
。