BZOJ2492 Revenge of Fibonacci

首先我们高精度加法算出前10W个数。。。

然后把所有的前40位搞出来建成trie树,于是就变成了模板题了。。。

说一下。。。这题要是直接建出来son[tot][10]会MLE。。。所以。。。建trie树的时候得像建普通树一样add_edge

QAQ卡内存sxbk

  1 /**************************************************************
  2     Problem: 2492
  3     User: rausen
  4     Language: C++
  5     Result: Accepted
  6     Time:2836 ms
  7     Memory:71184 kb
  8 ****************************************************************/
  9  
 10 #include <cstdio>
 11 #include <cstring>
 12 #include <algorithm>
 13 #include <map>
 14  
 15 using namespace std;
 16 const int radix = 1e8;
 17 const int Mx = 1e5;
 18 const int N = 3600000;
 19  
 20 struct fib {
 21     int l, x[4096];
 22      
 23     inline void zero() {
 24         memset(x, 0, sizeof(x));
 25         l = 1;
 26     }
 27     inline void one() {
 28         memset(x, 0, sizeof(x));
 29         x[0] = l = 1;
 30     }
 31     inline int& operator [] (const int &p) {
 32         return x[p];
 33     }
 34      
 35     inline fib operator + (const fib &b) const {
 36         static fib res;
 37         static int i;
 38         res.zero(), res.l = max(l, b.l);
 39         for (i = 0; i < res.l; ++i) {
 40             res[i] += x[i] + b.x[i];
 41             res[i + 1] = res[i] / radix, res[i] %= radix;
 42         }
 43         if (res[res.l]) ++res.l;
 44         return res;
 45     }
 46 } a, b, c;
 47  
 48 char ch[64];
 49  
 50 struct edge {
 51     int next, to, t;
 52     edge() {}
 53     edge(int _n, int _to, int _t) : next(_n), to(_to), t(_t) {}
 54 } e[N];
 55 int first[N], tot, pos[N], cnt_T;
 56  
 57 inline void add_edge(const int &x, const int &y, const int &t) {
 58     e[++tot] = edge(first[x], y, t), first[x] = tot;
 59 }
 60  
 61 inline int find(const int &p, const int &t) {
 62     static int x;
 63     for (x = first[p]; x; x = e[x].next)
 64         if (e[x].t == t) return e[x].to;
 65     return 0;
 66 }
 67  
 68 #define Pos pos[p]
 69 inline void trie_insert(char* ch, const int &len, const int &P) {
 70     static int p, i, t;
 71     for (p = i = 0; i < len; ++i) {
 72         t = ch[i] - '0';
 73         if (!find(p, t)) {
 74             add_edge(p, ++cnt_T, t);
 75             p = cnt_T;
 76         } else p = find(p, t);
 77         if (Pos == 0) Pos = P + 1;
 78     }
 79 }
 80  
 81 inline void trie_query(char *ch, const int &len) {
 82     static int p, i, t;
 83     for (p = i = 0; i < len; ++i) {  
 84         t = ch[i] - '0';
 85         if ((p = find(p, t)) == 0) {
 86             puts("-1");
 87             return;
 88         }
 89     }
 90     printf("%d
", Pos - 1);
 91 }
 92 #undef Pos
 93  
 94 int main() {
 95     int i, j, tot_len, tmp, len, Q, icase;
 96     a.one(), b.one();
 97     trie_insert("1", 1, 0);
 98     for (i = 2; i < Mx; ++i) {
 99         c = b + a, a = b, b = c, len = c.l;
100         tot_len = sprintf(ch, "%d", c[len - 1]);
101         for (j = 2; j <= len; ++j) {
102             tmp = sprintf(ch + tot_len, "%08d", c[len - j]);
103             if ((tot_len += tmp) >= 40) break;
104         }
105         tot_len = min(tot_len, 40);
106     trie_insert(ch, tot_len, i);
107     }
108     scanf("%d", &Q);
109     for (icase = 1; icase <= Q; ++icase) {
110         scanf("%s", ch);
111         len = strlen(ch);
112         printf("Case #%d: ", icase);
113         trie_query(ch, len);
114     }
115     return 0;
116 }
View Code
By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
原文地址:https://www.cnblogs.com/rausen/p/4361230.html