前缀数组
题目大意:给定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 <iostream>
#include <cstdio>
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