题目大意:给定$n$个正整数,求$[l,r]$中第$k$小的”好数“。$l,rleqslant10^{18},nleqslant62$,出现的其他数均$leqslant10^{50}$
好数定义为它至少包含这$n$个数中的一个
题解:二分答案,数位$DP$+$AC$自动机上$DP$,求一个数是第几个好数可以见[文本生成器](https://www.cnblogs.com/Memory-of-winter/p/11305126.html)
卡点:无
C++ Code:
#include <cstring> #include <cstdio> #include <algorithm> #include <iostream> #include <queue> const int maxn = 20 * 1000; long long n, k, l, r; long long f[20][maxn]; namespace AC { int nxt[maxn][10], fail[maxn], idx = 1; bool End[maxn]; void insert(std::string s) { int p = 1; for (char ch : s) { if (nxt[p][ch & 15]) p = nxt[p][ch &15]; else p = nxt[p][ch & 15] = ++idx; } End[p] = true; } void build() { std::queue<int> q; for (int i = 0; i < 10; ++i) if (nxt[1][i]) fail[nxt[1][i]] = 1, q.push(nxt[1][i]); else nxt[1][i] = 1; while (!q.empty()) { int u = q.front(); q.pop(); for (int i = 0; i < 10; ++i) if (nxt[u][i]) { fail[nxt[u][i]] = nxt[fail[u]][i]; End[nxt[u][i]] |= End[fail[nxt[u][i]]]; q.push(nxt[u][i]); } else nxt[u][i] = nxt[fail[u]][i]; } } int num[20], tot; long long calc(int x, int lim, int lead, int p) { if (!x) return lead; long long F = f[x][p]; if (~F && !lim && lead) return F; F = 0; for (int i = lim ? num[x] : 9, up = 1; ~i; --i, up = 0) if (!End[nxt[p][i]]) F += calc(x - 1, lim && up, lead || i, nxt[p][i]); if (~F && !lim && lead) f[x][p] = F; return F; } long long solve(long long x) { if (!x) return 0; long long X = x; tot = 0; while (x) num[++tot] = x % 10, x /= 10; return X - calc(tot, 1, 0, 1); } long long query(long long k, long long L, long long R) { long long base = solve(L - 1), l = L, r = R, ans = L; while (l <= r) { long long mid = l + r >> 1, t = solve(mid) - base; if (t >= k) r = mid - 1, ans = mid; else l = mid + 1; } if (solve(ans) - base != k) return -1; return ans; } } int main() { std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0); memset(f, -1, sizeof f); std::cin >> l >> r >> k >> n; for (int i = 0; i < n; ++i) { static std::string s; std::cin >> s; AC::insert(s); } AC::build(); std::cout << AC::query(k, l, r) << ' '; return 0; }