标签:
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 204800/204800 K (Java/Others)
Total Submission(s): 2582 Accepted Submission(s): 647
【思路】
高精度加法+Trie。
离线处理出F(99999)以内所有的F在长度40以内的前缀并构造一棵字典树。因为精度原因,保留60位进行加法计算就可以达到精确。
Trie的结点维护一个val表示经过该节点的所有字符串中的最小标号,对应每一个查询用O(maxn)的时间求解。
总的时间复杂度为O(99999*60+T*maxn)。
【代码】
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #define FOR(a,b,c) for(int a=(b);a<=(c);a++) 6 using namespace std; 7 8 const int sigmasize = 10; 9 //Trie相关 10 struct Node{ 11 int val; 12 Node* next[sigmasize]; 13 }; 14 struct Trie{ 15 Node *root; 16 Trie() { 17 root=new Node; 18 for(int i=0;i<sigmasize;i++) root->next[i]=NULL; 19 root->val=0; 20 } 21 int idx(char c) { return c-‘0‘; } 22 void insert(char* s,int v) { 23 int n=strlen(s); 24 Node* u=root; 25 for(int i=0;i<min(n,41);i++) { 26 int c=idx(s[i]); 27 if(u->next[c]==NULL) { 28 Node* tmp=new Node; 29 tmp->val=0; 30 for(int i=0;i<sigmasize;i++) tmp->next[i]=NULL; 31 u->next[c]=tmp; 32 } 33 u=u->next[c]; 34 if(u->val==0) u->val=v; 35 } 36 if(u->val==0) u->val=v; //存储最小的F 37 } 38 int find(char* s) { 39 int n=strlen(s); 40 Node* u=root; 41 for(int i=0;i<min(n,41);i++) { 42 int c=idx(s[i]); 43 if(u->next[c]==NULL) return 0; 44 else u=u->next[c]; 45 } 46 return u->val; 47 } 48 void del(Node *root) { 49 for(int i=0;i<sigmasize;i++) { 50 if(root->next[i]!=NULL) del(root->next[i]); 51 } 52 free(root); 53 } 54 }trie; 55 //题目相关 56 int n; 57 const int maxn = 100; 58 char F1[maxn],F2[maxn],Ftmp[maxn],s[maxn]; 59 char d[maxn]; 60 61 void Add(char *a,char *b,char *c) 62 { 63 int i,j,k,aa,bb,t=0,p=0; 64 aa=strlen(a)-1,bb=strlen(b)-1; 65 while(aa>=0||bb>=0) { 66 if(aa<0)i=0; else i=a[aa]-‘0‘; 67 if(bb<0)j=0; else j=b[bb]-‘0‘; 68 k=i+j+t; 69 d[p++]=k%10+‘0‘; 70 t=k/10; 71 aa--,bb--; 72 } 73 while(t) { 74 d[p++]=t%10+‘0‘; 75 t=t/10; 76 } 77 for(i=0;i<p;i++) c[i]=d[p-i-1]; 78 c[p]=‘\0‘; 79 } 80 81 int main() { 82 F1[0]=‘1‘,F1[1]=‘\0‘; 83 F2[0]=‘1‘,F2[1]=‘\0‘; 84 trie.insert(F1,1),trie.insert(F2,1); 85 FOR(i,2,100000-1) { 86 strcpy(Ftmp,F2); 87 int len1=strlen(F1),len2=strlen(F2); 88 if(len1>60) { 89 F1[60]=F2[60]=‘\0‘; 90 } 91 Add(F1,F2,F2); 92 trie.insert(F2,i+1); 93 strcpy(F1,Ftmp); 94 } 95 int T,kase=0; 96 scanf("%d",&T); 97 while(T--) { 98 scanf("%s",s); 99 int ans=trie.find(s); 100 if(!ans) ans=-1; else ans--; 101 printf("Case #%d: %d\n",++kase,ans); 102 } 103 trie.del(trie.root); 104 return 0; 105 }
HDU4099 Revenge of Fibonacci(高精度+Trie)
标签:
原文地址:http://www.cnblogs.com/lidaxin/p/4986233.html