当前位置: 首页 > news >正文

UVa 12333 Revenge of Fibonacci

题目描述

斐波那契数列的定义如下:

F(0)=F(1)=1F(n)=F(n−1)+F(n−2)∀n≥2 F(0) = F(1) = 1 \\ F(n) = F(n - 1) + F(n - 2) \quad \forall n \geq 2 F(0)=F(1)=1F(n)=F(n1)+F(n2)n2

给定多个测试用例,每个测试用例给出一个数字字符串(最多 404040 位),要求找到最小的索引 nnnn<100000n < 100000n<100000),使得 F(n)F(n)F(n) 的十进制表示以该字符串为前缀。如果不存在这样的 nnn,则输出 −1-11

题目分析

问题难点

  1. 大数处理:第 100000100000100000 个斐波那契数有大约 208992089920899 位,无法用标准数据类型存储
  2. 前缀匹配:需要高效匹配多个查询字符串的前缀
  3. 性能要求:最多 500005000050000 个测试用例,需要高效算法

关键观察

  • 我们只需要斐波那契数的404040来进行前缀匹配,但计算时必须保证这 404040 位的准确性
  • 由于查询是离线的,可以预处理所有查询,然后边计算斐波那契数边进行匹配
  • 使用 Trie\texttt{Trie}Trie 树可以高效地进行多模式前缀匹配

解题思路

1. 高精度计算

使用高精度加法来计算斐波那契数列。为了优化性能:

  • 采用 888 位压位(BASE=108\texttt{BASE} = 10^8BASE=108),减少计算和存储开销
  • 使用滚动数组,只存储最近 333 个斐波那契数
  • 数组 f[3][MAXN]\texttt{f[3][MAXN]}f[3][MAXN] 存储高精度数,其中 MAXN\texttt{MAXN}MAXN 是最大位数

2. 前缀匹配优化

构建 Trie\texttt{Trie}Trie 树来存储所有查询前缀:

  • 每个节点包含子节点指针数组 children[10]\texttt{children[10]}children[10] 和查询索引列表 idxs\texttt{idxs}idxs
  • 对于查询字符串 "123"\texttt{"123"}"123",在 Trie\texttt{Trie}Trie 中创建路径 1→2→31 \rightarrow 2 \rightarrow 3123,并将查询索引加入叶节点的 idxs\texttt{idxs}idxs 列表

3. 实时匹配策略

在计算每个斐波那契数时:

  1. 提取前 404040 位数字(考虑压位的前导零处理)
  2. Trie\texttt{Trie}Trie 中遍历匹配路径
  3. 如果到达包含查询索引的节点且未被访问过,记录答案并标记为已访问
  4. 当所有查询都找到答案时提前终止计算

4. 特殊处理

  • 查询 "1"\texttt{"1"}"1" 直接对应 F(0)F(0)F(0)F(1)F(1)F(1)
  • 使用 visited\texttt{visited}visited 标记避免重复处理
  • 计数器 cnt\texttt{cnt}cnt 跟踪已解决的查询数量

参考代码

// Revenge of Fibonacci
// UVa ID: 12333
// Verdict: Accepted
// Submission Date: 2025-10-29
// UVa Run Time: 0.320s
//
// 版权所有(C)2025,邱秋。metaphysis # yeah dot net#include <bits/stdc++.h>
using namespace std;
const int MAXN = 50010, WIDTH = 8, BASE = 100000000;
int f[3][MAXN];
struct node {bool visited;vector<int> idxs;node* children[10];node () { memset(children, visited = 0, sizeof children); }
} root;
int main() {cin.tie(0), cout.tie(0), ios::sync_with_stdio(false);int T;cin >> T;string prefix;int answer[MAXN], cnt = 0;memset(answer, -1, sizeof answer);for (int i = 1; i <= T; i++) {cin >> prefix;if (prefix == "1") { answer[i] = 0; cnt++; continue; }node* current = &root;for (auto c : prefix) {if (!current->children[c - '0']) current->children[c - '0'] = new node();current = current->children[c - '0'];}current->idxs.push_back(i);}int digits[110];int f1 = 0, f2 = 1, f3 = 2, length = 1;f[0][0] = 1, f[1][0] = 1;for (int i = 2; i < 100000; i++) {int carry = 0;for (int j = 0; j < length; j++) {f[f3][j] = f[f1][j] + f[f2][j] + carry;carry = f[f3][j] / BASE;f[f3][j] %= BASE;}if (carry) f[f3][length++] = carry;int ds = 0, firstBlock = 1;for (int j = length - 1; j >= 0 && ds <= 40; j--) {string block = to_string(f[f3][j]);if (firstBlock) firstBlock = 0;else while (block.length() < WIDTH) block = '0' + block;for(auto c : block) digits[ds++] = c - '0';}node* current = &root;for (int j = 0; j < ds; j++) {current = current->children[digits[j]];if (!current) break;if (current->idxs.size() && !current->visited) {current->visited = true;for (auto idx : current->idxs) answer[idx] = i;cnt += current->idxs.size();}}if (cnt == T) break;f1++, f2++, f3++;f1 %= 3, f2 %= 3, f3 %= 3;}for (int i = 1; i <= T; i++) cout << "Case #" << i << ": " << answer[i] << '\n';return 0;
}

总结

本题通过结合高精度计算和 Trie\texttt{Trie}Trie 树前缀匹配,高效解决了大规模斐波那契数前缀查询问题。关键点在于:

  1. 压位高精度优化计算效率
  2. Trie\texttt{Trie}Trie 树实现多模式前缀匹配
  3. 实时匹配和提前终止策略
  4. 特殊情况的优化处理

这种思路可以扩展到其他需要处理大数序列前缀匹配的问题中。

http://www.dtcms.com/a/544432.html

相关文章:

  • rank(A+E) >= rank(A)证明
  • 未来之窗昭和仙君(四十三)开发布草管理系统修仙版——东方仙盟筑基期
  • VMware 虚拟机网络故障
  • 河南省建设厅举报网站建网站需要多少资金
  • 网站开发常用的谷歌插件企业首次建设网站的策划流程
  • 计算机3D视觉:Pytorch3d的环境配置与初步使用
  • 国产化转型实战:制造业供应链物流系统从MongoDB至金仓数据库迁移全指南
  • 从零开始学 Rust:环境搭建、基础语法到实战项目全流程
  • S11e Protocol 完整白皮书
  • CUDA:通往大规模并行计算的桥梁
  • AR智能眼镜:变电站巡检误操作的“电子安全员”
  • Rust 中的内存对齐与缓存友好设计:性能优化的隐秘战场
  • Springboot3+mqttV5集成(Emqx 5.8.3版本)
  • 东莞网站建设设技术支持网站
  • 高州网站建设公司欧洲vodafonewifi18mmpcc
  • 第二章、Docker+Ollama封神!2步装Qwen+Deepseek小型模型
  • Rust——Trait 定义与实现:从抽象到实践的深度解析
  • Spring AI加DeepSeek实现一个Prompt聊天机器人
  • 怎么判断我的电脑是否支持PCIe 5.0 SSD?Kingston FURY Renegade G5
  • Kotlin Map扩展函数使用指南
  • 批量地址解析坐标,支持WPS、EXCEL软件,支持导出SHP、GEOJSON、DXF等文件格式
  • 【Docker】【2.docker 安装 ubuntu 桌面版】
  • 单片机上的动态数码管
  • 怎么创建网站相册甘肃网站建设项目
  • 前端三剑客之一 CSS~
  • 仓颉语言运算符使用方法详解
  • 视频编码原理
  • 房管局网站建设网站备案要求
  • 2025-TMLR-Piecewise Constant Spectral Graph Neural Network
  • MATLAB(Matrix Laboratory,矩阵实验室)