HDU 4518
整理一下思路,明天再写。。。
这道题,其实就是求包含大于10的斐波那切数字的第K(K是斐波那契数)个数。注意到斐波那契数的爆炸性增长,所以在范围 内的符合要求的F数并不多吧。比如求第K个F数,那么,前K个F数都是这样的数,组成它们的数字中有斐波那契数。这就是字符串匹配吧。把这些数转化成字符串匹配,也就是很经典的数位DP,求范围内含有这些数字的数有多少个。
但是,所要含的数有很多个,怎么样匹配呢?转化成字符串,构成AC自动机来做。但是,说实话,求含有数字的个数确实不好弄,没关系,把它转化成不含有就容易了。于是,就成了AC自动机+数位DP了。但是,我们要求的是第K个,那么,因为个数是单调增的,求出刚好第K个可以使用二分查找来办到。
使用AC自动机来做数位DP,首先要构建trie图,然后明白哪些状态是可转移或不可转移的,然后在trie图上进行DP就可以了。
dp[i][j],即是当前是前第i位数位,并处在自动机的j状态上。
#include <iostream>
#include <cstdio>
#define LL __int64
using namespace std; const LL inf=10000000000000ll;
const int root=;
LL f[],ans[]; int trie[][],bit[],fail[],que[],head,tail;
int tot;
int nxt[][];
LL dp[][];
bool tag[]; void insert(LL now){
int len=;
while(now){
bit[++len]=now%;
now/=;
}
int p=root,i=len;
while(i--){
if(trie[p][bit[i+]]==-){
trie[p][bit[i+]]=++tot;
}
p=trie[p][bit[i+]];
}
tag[p]=true;
} void build_ac(){
head=tail=;
que[tail++]=root;
while(head!=tail){
int tmp=que[head++];
int p=-;
for(int i=;i<;i++){
if(trie[tmp][i]!=-){
if(tmp==root) fail[trie[tmp][i]]=root;
else{
p=fail[tmp];
while(p!=-){
if(trie[p][i]!=-){
fail[trie[tmp][i]]=trie[p][i];
break;
}
p=fail[p];
}
if(p==-) fail[trie[tmp][i]]=root;
}
if(tag[fail[trie[tmp][i]]]) tag[trie[tmp][i]]=tag[fail[trie[tmp][i]]];
que[tail++]=trie[tmp][i];
}
else{
if(tmp==root) trie[tmp][i]=root;
else{
p=fail[tmp];
while(p!=-){
if(trie[p][i]!=-){
trie[tmp][i]=trie[p][i];
break;
}
p=fail[p];
}
if(p==-) trie[tmp][i]=root;
}
}
}
}
} LL dfs(int len,int j,bool flag){
if(len==) return 1ll;
if(!flag&&dp[len][j]!=-) return dp[len][j];
LL ans=;
int up=flag?bit[len]:;
for(int i=;i<=up;i++){
if(tag[nxt[j][i]]||nxt[j][i]==-) continue;
ans+=dfs(len-,nxt[j][i],i==up&&flag);
}
if(!flag) dp[len][j]=ans;
return ans;
} LL cal(LL m){
LL tm=m+1ll;
int len=;
while(m){
bit[++len]=m%;
m/=;
}
return tm-dfs(len,,true);
// return 0;
} LL bin(LL num){
// cout<<cal(13)<<endl;
// system("pause");
LL l=,r=inf,ret=-,tmp;
while(l<=r){
LL m=(l+r)>>;
if((tmp=cal(m))>=num){
r=m-;
ret=m;
// cout<<m<<endl;
}
else l=m+;
}
return ret;
} int cal_next(int p,int j){
if(tag[p]) return -;
if(tag[trie[p][j]]) return -;
return trie[p][j];
} void Init(){
tot=;
memset(trie,-,sizeof(trie));
memset(tag,false,sizeof(tag));
memset(fail,-,sizeof(fail));
f[]=1ll; f[]=1ll;
for(int i=;i<=;i++){
f[i]=f[i-]+f[i-];
if(f[i]>){
insert(f[i]);
}
}
build_ac();
for(int i=;i<=tot;i++){
for(int j=;j<;j++)
nxt[i][j]=cal_next(i,j);
}
memset(dp,-,sizeof(dp));
int c=;
for(int i=;i<=;i++){
ans[c]=bin(f[i]);
// system("pause");
if(ans[c]==-) break;
c++;
// printf("%I64d %d\n",ans[c-1],c);
}
} int main(){
Init();
LL n;
// cout<<"YES"<<endl;
while(scanf("%I64d",&n)!=EOF&&n!=-){
LL ret=inf;
for(int i=;i<;i++){
LL tmp=n-ans[i];
// cout<<tmp<<endl;
if(tmp<) tmp=-tmp;
if(ret>tmp) ret=tmp;
}
printf("%I64d\n",ret);
}
return ;
}
HDU 4518的更多相关文章
- HDOJ 2111. Saving HDU 贪心 结构体排序
Saving HDU Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- 【HDU 3037】Saving Beans Lucas定理模板
http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...
- hdu 4859 海岸线 Bestcoder Round 1
http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...
- HDU 4569 Special equations(取模)
Special equations Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u S ...
- HDU 4006The kth great number(K大数 +小顶堆)
The kth great number Time Limit:1000MS Memory Limit:65768KB 64bit IO Format:%I64d & %I64 ...
- HDU 1796How many integers can you find(容斥原理)
How many integers can you find Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%I64d ...
- hdu 4481 Time travel(高斯求期望)(转)
(转)http://blog.csdn.net/u013081425/article/details/39240021 http://acm.hdu.edu.cn/showproblem.php?pi ...
- HDU 3791二叉搜索树解题(解题报告)
1.题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=3791 2.参考解题 http://blog.csdn.net/u013447865/articl ...
- hdu 4329
problem:http://acm.hdu.edu.cn/showproblem.php?pid=4329 题意:模拟 a. p(r)= R'/i rel(r)=(1||0) R ...
随机推荐
- iOS地图集成示例:百度地图POI检索
一.集成百度地图(傻瓜教程,以网站说明文档为准,此处罗列几项主要步骤) 1.登录 http://lbsyun.baidu.com 百度地图开发者平台,获取SDK和集成文档. 2.百度地图可以提供的 ...
- Appium + python -小程序实例
from appium import webdriverfrom appium.webdriver.common.touch_action import TouchActionfrom time im ...
- 快速搭建ELK集中化日志管理平台
由于我们的项目是分布式,服务分布于多个服务器上,每次查看日志都要登录不同服务器查看,而且查看起来还比较麻烦,老大让搭一个集中化日志管理的东西,然后就在网上找到了这个东西ELK ELK就是elastic ...
- jQuery考试之错题分析
获取元素范围大小顺序依次为: $(#one).siblings("div")>$("#one~div")>$("#one +div&quo ...
- 我和CSDN的那些事
作者:朱金灿 来源:http://blog.csdn.net/clever101 前些日子收到这样一个邀请: CSDN的工作人员还来电给我确认是否能参加.开始我有点犹豫,毕竟是在工作日的晚上,毕竟离我 ...
- 联想笋尖S90(S90-t 、S90-u)解锁BootLoader
工具下载链接: http://pan.baidu.com/s/1eSgZuka 备用下载链接: http://pan.baidu.com/s/1dFKqSId 本篇教程,仅限于联想笋尖S90(S90- ...
- 【SQL】联合语句
一.UNION操作符 UNION 操作符用于合并两个结果集,在合并的同时去掉重复行,并按合并后结果的第一列升序排列.合并后结果集的列名由第一个结果集的列名确定. UINON连接的两个结果集必须具有相同 ...
- 【sqli-labs】 less4 GET - Error based - Double Quotes - String (基于错误的GET双引号字符型注入)
提交id参数 加' http://localhost/sqli/Less-4/?id=1' 页面正常,添加" http://localhost/sqli/Less-4/?id=1" ...
- BZOJ 1984月下“毛景树” LCT维护边权 + 下传标记
Description 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里.爬啊爬~爬啊爬~~毛毛虫爬到了一颗小小的“毛景树” ...
- luogu P4719 【模板】动态 DP 矩阵乘法 + LCT
方法二:LCT+矩阵乘法 上文中,我们用线段树来维护重链上的各种矩阵转移. 第二种方法是将树链剖分替换为动态树. 我们知道,矩阵乘法 $\begin{bmatrix} F_{u,0} & F_ ...