前缀统计

前缀数组

题目大意:给定N个字符串S1,S2,...,SN。接下来进行M次询问,每次询问给定一个字符串T,求S1~SN

中又多少个字符串是T的前缀。

数据范围:输入字符串的总长度不超过10^6。

题目解析:1. 对于一些对数据结构还不太熟悉的OIer们,可以在每次访问时,从1~N查询一遍,比较是否为T的前缀,并用ans                         记录总数。【复杂度:O(n^2) 】。

                 2. 可以尝试建立一个Tire树,将N个字符串插入其中。同时每个节点上储存一个整数sum,记录该节点是多少个字符                       串的末尾节点。


代码如下:

#include 
#include 

using namespace std;

const size_t	_M_size(1 << 27);
char		_M_pool[_M_size], *_M_cur(_M_pool + _M_size);
inline void* operator new(size_t size)
{ return _M_cur -= size; }
inline void operator delete(void* ) { }

struct node {
	int	sum;
	node	*ch[26];
} *root = new node;

void insert(const char *s)
{
	node	*o = root;
	while(*s) {
		if(!o->ch[*s - 'a'])
			o->ch[*s - 'a'] = new node;
		o = o->ch[*s++ - 'a'];
	}
	++(o->sum);
}

int query(const char *s)
{
	node	*o = root;
	int	res = 0;
	while(*s && o) {
		res += o->sum;
		o = o->ch[*s++ - 'a'];
	}
	if(o)
		res += o->sum;
	return res;
}

const size_t	MaxL = 1000005;

char	S[MaxL];

int main()
{
	int	n;

	cin >> n;
	while(n--)
		scanf("%s", S), insert(S);

	cin >> n;
	while(n--)
		scanf("%s", S), printf("%d\n", query(S));

	return 0;
}
左岸夜亦冷

2018.4.27

你可能感兴趣的:(前缀统计)