hdu 4099 Revenge of Fibonacci Trie树与模拟数位加法
Posted hxer
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 4099 Revenge of Fibonacci Trie树与模拟数位加法相关的知识,希望对你有一定的参考价值。
Revenge of Fibonacci
题意:给定fibonacci数列的前100000项的前n位(n<=40);问你这是fibonacci数列第几项的前缀?如若不在前100000项范围内,输出-1;
思路:直接使用数组模拟加法,再用Trie树插入查找即可;但是一般使用new Trie()的代码都是MLE的。反而我之前写的,直接得到数组大小的maxnode版本的内存可以接受;并且还有一点就是前40位的精度问题;由于是自己计算出来的finboncci数列,并不是系统给的,所以1的进位不会形成递推的形式,但是也不能只计算到40+位..代码中是计算到了前60位,然后只往Trie中传了40位,还有一点就是要维护前60位的值,即当位数增加时,逐渐地将地位舍去;
#include<iostream> #include<cstdio> #include<cstring> #include<string.h> #include<algorithm> #include<vector> #include<cmath> #include<stdlib.h> #include<time.h> #include<stack> #include<set> #include<map> #include<queue> using namespace std; #define rep0(i,l,r) for(int i = (l);i < (r);i++) #define rep1(i,l,r) for(int i = (l);i <= (r);i++) #define rep_0(i,r,l) for(int i = (r);i > (l);i--) #define rep_1(i,r,l) for(int i = (r);i >= (l);i--) #define MS0(a) memset(a,0,sizeof(a)) #define MS1(a) memset(a,-1,sizeof(a)) #define MSi(a) memset(a,0x3f,sizeof(a)) #define inf 0x3f3f3f3f #define lson l, m, rt << 1 #define rson m+1, r, rt << 1|1 typedef pair<int,int> PII; #define A first #define B second #define MK make_pair typedef __int64 ll; template<typename T> void read1(T &m) { T x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} m = x*f; } template<typename T> void read2(T &a,T &b){read1(a);read1(b);} template<typename T> void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);} template<typename T> void out(T a) { if(a>9) out(a/10); putchar(a%10+‘0‘); } const int maxl = 1e5*45 + 7; const int sigma_size = 10; struct Trie{ int val[maxl],sz; int ch[maxl][10]; Trie(){sz = 1;MS0(ch[0]);} void Insert(char *s,int v) { int u = 0,len = strlen(s); rep0(i,0,len){ int c = s[i]-‘0‘; if(ch[u][c] == 0){ MS0(ch[sz]); val[sz] = v; ch[u][c] = sz++; } u = ch[u][c]; } if(val[u] == 0) val[u] = v;//不能直接覆盖; } int Find(char *s) { int u = 0,len = strlen(s); rep0(i,0,len){ int c = s[i]-‘0‘; if(ch[u][c] == 0) return 0; u = ch[u][c]; } return val[u]; } }trie; int a[60],b[60],c[60]; void init() { char s[60] = {‘1‘}; a[0] = 1;b[0] = 1; trie.Insert(s,1); rep0(i,2,100000){ int r = 0,cnt = 0; rep1(j,0,60){ c[j] = a[j]+b[j]+r; r = c[j]/10; c[j] = c[j]%10; } int id = -1; rep_1(j,60,0){ if(id < 0 && c[j]) id = j; if(~id){ s[cnt++] = c[j]+‘0‘; } if(cnt >= 40) break; } s[cnt] = ‘\0‘; trie.Insert(s,i+1); if(id >= 55){ //防止进位误差,舍去后面一位; rep1(j,1,60) c[j-1] = c[j],b[j-1] = b[j]; c[60] = b[60] = 0; } rep1(j,0,60){ a[j] = b[j]; b[j] = c[j]; } } } int main() { init(); int kase = 1,T; read1(T); char str[45]; while(T--){ scanf("%s",str); printf("Case #%d: %d\n",kase++,trie.Find(str)-1); } return 0; }
以上是关于hdu 4099 Revenge of Fibonacci Trie树与模拟数位加法的主要内容,如果未能解决你的问题,请参考以下文章
[ACM] HDU 5086 Revenge of Segment Tree(全部连续区间的和)
HDU 4898 The Revenge of the Princess’ Knight (后缀数组+二分+贪心+...)