hdu4099(Trie)

题意:

  给定一个长度不超过40的数字串s,求斐波那契数列的前十万项中,最小的一个前缀为s的数的下标。

解决:

  高精度算出前十万个斐波那契数,每个取前40位,建trie,查询O(40)

(本地建立Trie跑了20s,让我知道了为啥服务器那么贵)

  1 #include <bits/stdc++.h>
  2 
  3 int a[22000], b[22000], c[22000];
  4 int l1, l2, l3;
  5 int op[55], len;
  6 
  7 struct Node{
  8     Node *ch[10];
  9     int ans;
 10     Node()
 11     {
 12         for (int i = 0; i < 10; ++i)
 13             ch[i] = NULL;
 14         ans = -1;
 15     }
 16 };
 17 
 18 struct Trie{
 19     Node *root;
 20     void init()
 21     {
 22         root = new Node();
 23     }
 24     void trieInsert(int index)
 25     {
 26         Node *p = root;
 27         for (int i = l3; i >= std::max(l3-39, 1); --i) {
 28             if ( p -> ch[c[i]] == NULL) {
 29                 p -> ch[c[i]] = new Node();
 30                 p-> ch[c[i]] -> ans = index;
 31             }
 32             p = p ->ch[c[i]];
 33         }
 34         p -> ans = index;
 35     }
 36     int trieQuery()
 37     {
 38         Node *p = root;
 39         for (int i = 1; i <= len; ++i) {
 40             if ( p -> ch[op[i]] == NULL)
 41                 return -1;
 42             p = p -> ch[op[i]];
 43         }
 44         return p -> ans;
 45     }
 46 }tr;
 47 
 48 void add()
 49 {
 50     int carry = 0;
 51     for (int i = 1; i <= std::max(l1, l2); ++i) {
 52         c[i] = a[i] + b[i] + carry;
 53         if (c[i] >= 10) {
 54             carry = 1;
 55             c[i] -= 10;
 56         }
 57         else
 58             carry = 0;
 59     }
 60     if (carry == 1) {
 61         c[++l3] = 1;
 62     }
 63 }
 64 
 65 void init()
 66 {
 67     tr.init();
 68     memset(a, 0, sizeof a);
 69     memset(b, 0, sizeof b);
 70     memset(c, 0, sizeof c);
 71     a[++l1] = 1;
 72     b[++l2] = 1;
 73     c[++l3] = 1;
 74     tr.trieInsert(0);
 75     for (int i = 2; i < 100000; ++i) {
 76         add();
 77         tr.trieInsert(i);
 78         for (int j = 1; j <= l2; ++j) {
 79             a[j] = b[j];
 80         }
 81         for (int j = 1; j <= l3; ++j) {
 82             b[j] = c[j];
 83         }
 84         l1 = l2;
 85         l2 = l3;
 86     }
 87 }
 88 
 89 char buf[55];
 90 
 91 int main()
 92 {
 93     init();
 94     int T;
 95     scanf("%d", &T);
 96     for (int t = 1; t <= T; ++t) {
 97         scanf("%s", buf+1);
 98         len = strlen(buf+1);
 99         for (int i = 1; i <= len; ++i) {
100             op[i] = buf[i] - '0';
101         }
102         printf("Case #%d: %d
", t, tr.trieQuery());
103     }
104 }
原文地址:https://www.cnblogs.com/takeoffyoung/p/4940185.html