(trie树)LA 3942

来源:互联网 发布:智慧树网络课程注册 编辑:程序博客网 时间:2024/06/05 02:59

Trie树,又称单词查找树、字典树,是一种树形结构,是一种哈希树的变种,是一种用于快速检索的多叉树结构。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。
Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。
Trie树也有它的缺点,Trie树的内存消耗非常大.当然,或许用左儿子右兄弟的方法建树的话,可能会好点.
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1943
DP:dp[i]表示从字符i开始的字符串(即后缀S[i...L])的分解方案数,则dp[i] = sum{dp[i+len[x]] | 单词x是S[i...L]的前缀}。
#include <cstdio>#include <cstring>using namespace std;const int maxnode = 4000 * 100 + 10;const int sigma_size = 26;const int MOD = 20071027;int n, dp[300000 + 10];char str[300000 + 10], s[100 + 10];struct Trie{      int ch[maxnode][sigma_size];      int val[maxnode];      int next;      void init()      {            next = 0;            val[0]= 0;            memset(ch[0], 0, sizeof(ch[0]));      }      void insert(char *s, int v)      {            int len = strlen(s), cur = 0, idx;            for (int i=0; i<len; ++i)            {                  idx = s[i] - 'a';                  if (!ch[cur][idx])                  {                        ch[cur][idx] = ++next;                        val[next] = 0;                        memset(ch[next], 0, sizeof(ch[next]));                  }                  cur = ch[cur][idx];            }            val[cur] = v;      }      int find(char *s, int pos)      {            int len = strlen(s), cur = 0, idx, ans = 0;            for (int i=pos; i<len; ++i)            {                  if (s[i]=='\0')                        break;                  idx = s[i] - 'a';                  if (ch[cur][idx]==0)                        break;                  cur = ch[cur][idx];                  if (val[cur]==1)                        ans = (ans + dp[i+1]) % MOD;//            }            return ans;      }}v;int main(){      int Case = 1;      while (~scanf("%s%d", str, &n))      {            v.init();            for (int i=0; i<n; ++i)            {                  scanf("%s", s);                  v.insert(s, 1);            }            int len = strlen(str);            dp[len] = 1;            for (int i=len-1; i>=0; --i)                  dp[i] = v.find(str, i);            printf("Case %d: %d\n", Case++, dp[0]);      }      return 0;}

原创粉丝点击