码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 2846 Repository 字典树

时间:2015-08-01 22:02:52      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:hdu 2846   repository   字典树   

//	hdu 2846 Repository 字典树
//
//	题目大意:
//		
//		有n个字符串,m个待询问的字符串,问这些字符串里面以该询问的
//		字符串为子串的字符串有多少个
//
//	解题思路:
//		
//		字典树,将字符串的所有子串插入到字典树中,并设立一个No.标识
//		以免重计数。最后查询就好了
//
//	感悟:
//		
//		这题的数据量有点大,虽然p是10000,但是长度是20,单个字符串的
//		最大子串数粗略的估计是 20 * 20 ,所以开的空间也要比较大。开始
//		开的是30w,返回了wa,开了40w,还是返回wa,开了50w,结果轻松Ac
//		啦~,继续加油哟~~~FIGHTING
	

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int MAX_N = 500000;

struct Trie{

	int ch[MAX_N][26];
	int sz;
	int val[MAX_N];
	int no[MAX_N];

	void init(){
		sz = 1;
		memset(ch[0],0,sizeof(ch[0]));
		val[0] = 0;
		no[0] = 0;
	}

	int idx(char c){
		return c - 'a';
	}

	void insert(char *s,int st,int ed,int v){
		int u = 0;
		//int n = strlen(s);
		for (int i=st;i<=ed;i++){
			int c = idx(s[i]);

			if (no[u]!=v)	// 这里是为了不重复计数,如果插入的点
				val[u]++;   // 是当前的串的子串,所有的该串子串都
							// 会有特定的v的标记,碰到了就避免计数

			if (!ch[u][c]){
				memset(ch[sz],0,sizeof(ch[sz]));
				val[sz] = 0;
				no[sz] = 0;
				ch[u][c] = sz++;
			}
			u = ch[u][c];
		}
		if (no[u]!=v)  // 不要忘了在插入的末尾,可能还会有相同的子串诺
			val[u]++;
		no[u] = v;
	}

	int query(char *s){
		int u = 0;
		int n = strlen(s);
		for (int i=0;i<n;i++){
			int c = idx(s[i]);
			if (!ch[u][c]){
				return 0;
			}

			u = ch[u][c];
		}
		return val[u];
	}



}trie;

void print(char *s,int st,int ed,int num){
	printf("%d \n\n",num);
	for (int i=st;i<=ed;i++){
		printf("%c",s[i]);
	}
	cout << endl;
}

int n,m;
bool vis[10009];
void input(){
	trie.init();
	char s[30];
	for (int i=1;i<=n;i++){
		scanf("%s",s);
		int len = strlen(s);
		for (int j=len-1;j>=0;j--){
			for (int k=j;k<len;k++){
				trie.insert(s,j,k,i);
				//print(s,j,k,i);
			}
		}
	}
	scanf("%d",&m);
	for (int i=1;i<=m;i++){
		scanf("%s",s);
		printf("%d\n",trie.query(s));

	}

	//memset(vis,0,sizeof(vis))
	
}

int main(){
	//freopen("1.txt","r",stdin);
	while(scanf("%d",&n)!=EOF){
		input();
	}
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

hdu 2846 Repository 字典树

标签:hdu 2846   repository   字典树   

原文地址:http://blog.csdn.net/timelimite/article/details/47190769

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!