HDU 2846 Trie查询
2015-11-09 22:29
337 查看
给出若干模式串,再给出若干询问串,求每个询问串作为多少个模式串的子串出现。
如果一个串是另一个串的子串,则一定是另一个串某个前缀的后缀或者某个后缀的前缀。根据字典树的性质,将模式串的每一个后缀插入字典树中,同时更新字典树中节点的cnt值。这里需要注意不要重复累加贡献,可以在字典树中新增一个num的信息值来实现这一点。
View Code
如果一个串是另一个串的子串,则一定是另一个串某个前缀的后缀或者某个后缀的前缀。根据字典树的性质,将模式串的每一个后缀插入字典树中,同时更新字典树中节点的cnt值。这里需要注意不要重复累加贡献,可以在字典树中新增一个num的信息值来实现这一点。
#include <iostream> #include <vector> #include <algorithm> #include <string> #include <string.h> #include <stdio.h> #include <queue> #include <stack> #include <map> #include <set> #include <cmath> #include <ctime> #include <cassert> #include <sstream> using namespace std; const int N=223456; const int MOD=1e9+7; const int CHARSET=26,BASE='a',MAX_NODE=10000*20*26+5000; struct Trie { int tot,root,child[MAX_NODE][CHARSET]; int flag[MAX_NODE],num[MAX_NODE]; Trie(){ init(); } void init(){ tot=0; root=newNode(); } int newNode() { ++tot; memset(child[tot],0,sizeof(child[tot])); flag[tot]=0; num[tot]=-1; return tot; } void insert(const char *str,int id){ int *cur=&root; for (const char *p=str;*p;++p){ cur=&child[*cur][*p-BASE]; if (*cur==0){ *cur=newNode(); } if (num[*cur]!=id) flag[*cur]++; num[*cur]=id; } } int query(const char *str){ int *cur=&root; for (const char *p=str;*p&&(*cur);++p){ cur=&child[*cur][*p-BASE]; } return flag[*cur]; } }trie; int main () { int n; scanf("%d",&n); char s[120]; for (int i=1;i<=n;i++) { scanf("%s",s); int len=strlen(s); for (int j=0;j<len;j++) trie.insert(s+j,i); } int Q; scanf("%d",&Q); while (Q--) { scanf("%s",s); int ret=trie.query(s); printf("%d\n",ret); } return 0; }
View Code
相关文章推荐
- 缓存
- 蓝懿iOS 技术内容交流和学习心得 11.9
- GET 与 POST比较
- 20121109
- JS数组
- 07-图6 旅游规划
- 广州一期各项练习心得
- IOS开发之保存图片到Documents目录及PNG,JPEG格式相互转换
- require.js 入门学习 (share)
- 一些前端页面的插件
- FPGA研发之道(25)-管脚
- Tomcat的版本、Servlet/JSP版本、JavaEE版本、JavaSE版本 四者之间的对应关系。
- 搭建lamp环境
- hibernate
- 【好文收藏】理解python多线程
- 如何学好C++语言
- Android Studio 快捷键
- 习题9-3 UVA1629(dp)
- 习题9-3 UVA1629(dp)
- 黑马程序员——基础知识——String