定義 F數:十進制表示中包含至少一個 ≥10 的斐波那契數(13, 21, 34, 55, 89, 144...)作為子串。最終數:在 F數序列中,下標也是斐波那契數的那些 F數。給定 n (≤ 10^11),求離 n 最近的最終數與 n 的差的絕對值。
struct Trie {
int next[1010][10], end[1010], fail[1010];
int root, L;
void init() { L = 0; root = newnode(); }
int newnode() { ... }
void insert(int x) { ... } // 從低位向高位插入
void build() { ... } // BFS 構建 fail,合併 end 標記
} ac;
long long dp[15][1010], suf[15], num[15], POW[20];
long long dfs(int pos, int st, bool flag) {
if (pos == 0) return 0;
if (flag && dp[pos][st] != -1) return dp[pos][st];
int u = flag ? 9 : num[pos];
long long ans = 0;
for (int i = 0; i <= u; i++) {
int nst = ac.next[st][i];
if (ac.end[nst]) {
if (flag || i < u) ans += POW[pos - 1];
else ans += suf[pos - 1] + 1;
} else ans += dfs(pos - 1, nst, flag || i < u);
}
if (flag) dp[pos][st] = ans;
return ans;
}
long long cal(long long x) { // 計算 ≤x 的 F數個數
// 分解數位到 num[], 計算 suf[] 前綴值
return dfs(len, ac.root, 0);
}
// 主程序預計算 seq[i] (i=2..56)
for (int i = 2; i <= 56; i++) {
long long l = 13, r = POW[12];
while (l < r) {
long long mid = (l + r) / 2;
if (cal(mid) < fib[i]) l = mid + 1;
else r = mid;
}
seq[i] = l;
}