2025.10.24
C.
枚举 gcd ,将所有边权是其倍数的边拿出来,对每个连通块处理直径。
最后取后缀 \(\max\) 。
每条边会被处理因数个数次,总复杂度 \(\mathcal O(n\sqrt n)\) ,上界很松。
D.
考虑维护哪些长度的弱循环节是合法的,如果对于当前 \(A_i\) 不合法,那么对于之后的所有 \(A_i\) 都不合法。
所以每个长度 \(\ell\) 出现的时间一定是一段区间,形如 \([\ell, r_{\ell}]\) 。
(时间指的是 \(A_i\) )
二分找到 \(r_{\ell}\) ,那么在这段时间里长度 \(\ell\) 是被激活的。
将询问挂在 pos 上,扫描线维护即可。
激活/熄灭可以看作 \(\pm inf\) 。
此题卡自然溢出 Hash 。
点击查看
#include <bits/stdc++.h>
#define lep(i, a, b) for (int i = (a), ed##i = (b); i <= ed##i; ++i)
#define rep(i, a, b) for (int i = (a), ed##i = (b); i >= ed##i; --i)
#define il inline
#define arr(ty, tn) std::array<ty, tn>
#define gmx(a, b) a = std::max(a, b)
#define gmn(a, b) a = std::min(a, b)
template <typename T>
void _debug(const T& t) { std::cerr << t << '\n'; }
template <typename T, typename... Args>
void _debug(const T& t, const Args&...res) { std::cerr << t << ' '; _debug(res...); }
#define debug(...) _debug(#__VA_ARGS__ " =", __VA_ARGS__)
const int LN = 5e5 + 7;
const int inf = 5e8;
const int mod = 1e9 + 7;
typedef long long ll;
typedef std::string str;
typedef std::pair<int, int> PII;
bool FIRPOS;
int n, m, q, a[LN], ans[LN], L[LN], R[LN];
ll A[LN], pw[LN];
int mn[LN << 2];
str S; std::vector <arr(int, 3)> o[LN];
std::vector <int> pos[LN], del[LN];
bool ENDPOS;
bool ck(int p, int l) { return (A[R[p] - l] - A[L[p] - 1] * pw[p - l] % mod + mod) % mod ==
(A[R[p]] - A[L[p] + l - 1] * pw[p - l] % mod + mod) % mod; }
#define ls p << 1
#define rs p << 1 | 1
#define md ((s + t) >> 1)
void bd(int s = 1, int t = m, int p = 1) {
if (s == t) return mn[p] = a[s] + inf, void();
bd(s, md, ls), bd(md + 1, t, rs); mn[p] = std::min(mn[ls], mn[rs]);
}
void mdy(int d, int v, int s = 1, int t = m, int p = 1) {
if (s == t) return mn[p] += v, void();
d <= md ? mdy(d, v, s, md, ls) : mdy(d, v, md + 1, t, rs); mn[p] = std::min(mn[ls], mn[rs]);
}
int qry(int l, int r, int s = 1, int t = m, int p = 1) {
if (r < s or t < l) return inf; if (l <= s and t <= r) return mn[p];
return std::min(qry(l, r, s, md, ls), qry(l, r, md + 1, t, rs));
}
#undef ls
#undef rs
#undef md
int main() {
std::ios::sync_with_stdio(false),
std::cin.tie(nullptr), std::cout.tie(nullptr);
int c1 = clock(), l, r, p;
std::cin >> S; n = S.size();
std::cin >> m;
lep(i, 1, m) std::cin >> a[i], pos[a[i]].emplace_back(i);
std::cin >> q;
lep(i, 1, q) std::cin >> p >> l >> r, o[p].push_back({l, r, i});
l = r = p = 0;
rep(i, n, 1) {
if (S[i - 1] >= 'A' and S[i - 1] <= 'Z') A[p + i] = S[i - 1] - 'A', L[i] = p + 1, R[i] = p + i;
else ++p, A[p] = S[i - 1] - 'a', L[i] = p, R[i] = p + i - 1;
}
pw[0] = 1;
lep(i, 1, n) pw[i] = pw[i - 1] * 19491001 % mod,
A[i] = (A[i - 1] * 19491001 % mod + A[i] * 17 % mod) % mod;
int md; bd();
lep(i, 1, n) {
l = i, r = n;
while (l < r) { md = (l + r + 1) >> 1;
if (ck(md, i)) l = md;
else r = md - 1;
} del[l + 1].emplace_back(i);
for (auto t : pos[i]) mdy(t, -inf);
for (auto c : del[i]) for (int t : pos[c]) mdy(t, inf);
for (auto t : o[i]) ans[t[2]] = qry(t[0], t[1]);
}
lep(i, 1, q) if (ans[i] > n) std::cout << "No answer!\n";
else std::cout << ans[i] << '\n';
std::cerr << clock() - c1 << " ms " << std::fabs(&ENDPOS - &FIRPOS) / 1024 / 1024 << " MB\n";
return 0;
}
时间仓促,如有错误欢迎指出,欢迎在评论区讨论,如对您有帮助还请点个推荐、关注支持一下

因数个数引理+Hash
浙公网安备 33010602011771号