UVa12333 Revenge of Fibonacci
Posted SilverNebula
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVa12333 Revenge of Fibonacci相关的知识,希望对你有一定的参考价值。
高精度 trie
暴力预处理出前100000个fibonacci数,将每个数的前40位数字串插入到trie中,记录每个结点最早可以由哪个数字串到达。
然后依次回答询问即可。
存fibonacci数的数组当然要滚动起来。
时限是10秒。本机试着卡了常数后跑了18秒(这个高精度写法好像本来就很慢),干脆交一波,UVA上7s AC
↑for循环i+=4 和直接一个register跑出来一样快,果然WC2017那道题只能在特定机子上做吗233
↑本机CPU是Intel I5-4590
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<queue> 6 #include<cstdlib> 7 #include<time.h> 8 using namespace std; 9 const int mxn=200010; 10 struct Num{ 11 int x[24501]; 12 int len; 13 friend Num operator + (Num a,Num b){ 14 a.len=max(a.len,b.len); 15 // printf("len:%d\n",a.len); 16 int ed=a.len/4*4; 17 for(int i=1;i<=ed;i+=4){ 18 a.x[i]+=b.x[i]; 19 a.x[i+1]+=b.x[i+1]; 20 a.x[i+2]+=b.x[i+2]; 21 a.x[i+3]+=b.x[i+3]; 22 } 23 for(int i=ed+1;i<=a.len;i++) 24 a.x[i]+=b.x[i]; 25 26 // for(register int i=1;i<=a.len;i++) a.x[i]+=b.x[i]; 27 28 for(int i=1;i<=a.len;i++){ 29 if(a.x[i]>=10){ 30 a.x[i+1]+=a.x[i]/10; 31 a.x[i]%=10; 32 } 33 } 34 if(a.x[a.len+1]) ++a.len; 35 return a; 36 } 37 }a[2]; 38 struct Trie{ 39 int t[4850007][10]; 40 int end[4850007]; 41 int cnt,rt; 42 void init(){ 43 memset(end,0x3f,sizeof end); 44 cnt=rt=1; 45 } 46 void insert(int id,Num a){ 47 int ed=a.len; 48 int st=max(1,a.len-40+1);//取高位40位 49 int now=rt; 50 for(int i=ed;i>=st;i--){ 51 if(!t[now][a.x[i]])t[now][a.x[i]]=++cnt; 52 now=t[now][a.x[i]]; 53 end[now]=min(end[now],id); 54 } 55 } 56 int query(char *s){ 57 int now=rt,len=strlen(s),tmp; 58 for(int i=0;i<len;i++){ 59 tmp=s[i]-‘0‘; 60 if(!t[now][tmp])return -1; 61 now=t[now][tmp]; 62 if(end[now]>100000)return -1; 63 } 64 return end[now]; 65 } 66 }tr; 67 void init(){ 68 a[0].len=1;a[0].x[1]=1; 69 a[1].len=1;a[1].x[1]=1; 70 tr.insert(0,a[0]); 71 tr.insert(1,a[1]); 72 for(int i=2;i<100000;i++){ 73 // printf("init:%d \n",i); 74 int tmp=i&1; 75 a[tmp]=a[tmp]+a[tmp^1]; 76 // for(int j=1;j<=a[tmp].len;j++)printf("%d ",a[tmp].x[j]); 77 // printf("%d cnt:%d\n",i,tr.cnt); 78 tr.insert(i,a[tmp]); 79 } 80 return; 81 } 82 char s[mxn]; 83 int n; 84 int main(){ 85 int i,j; 86 // clock_t a=clock(); 87 // printf("%d\n",a); 88 tr.init(); 89 init(); 90 // clock_t b=clock(); 91 // printf("%d\n",b); 92 // printf("fin: %d \n",b-a); 93 scanf("%d",&n); 94 for(i=1;i<=n;i++){ 95 scanf("%s",s); 96 printf("Case #%d: %d\n",i,tr.query(s)); 97 } 98 return 0; 99 }
以上是关于UVa12333 Revenge of Fibonacci的主要内容,如果未能解决你的问题,请参考以下文章
UVA-12333 Revenge of Fibonacci(竖式加法模拟 & 字典树)