题目链接:http://icpc.njust.edu.cn/Problem/Hdu/3695/

不加last指针的AC自动机会T,原因是他费了很多功夫在跳转上,而last指针是直接直到跳转的终止位置,直接跳转到终止位置上,所以只有一次跳转。未优化的fail指针最坏的情况下复杂度是O(|S|*|T|),其中|S|是模式串长度的均值,|T|是文本串的 长度。

代码如下:

 #include<bits/stdc++.h>
using namespace std;
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
const int INF = 0x3f3f3f3f;
const LL mod = 1e9+;
typedef pair<int,int> pll;
const int N = 1e6+;
int tot = ;
char str[N*], tmp[N*];
int trie[N*][], cnt[N*], fair[N*];
void init(){
for(int i = ; i < tot; i++){
for(int j = ; j < ; j++)
trie[i][j] = ;
}
tot = ;
}
void Insert(){
int rt = , len = strlen(str);
for(int i = ; i < len; i++){
int id = str[i] - 'A';
if(!trie[rt][id]) {
cnt[tot] = ;
fair[tot] = ;
trie[rt][id] = tot++;
}
rt = trie[rt][id];
}
cnt[rt]++;
}
void Build_tree(){
queue<int> q;
q.push();
int p;
while(!q.empty()){
int tmp = q.front();
q.pop();
for(int j = ; j < ; j++){
if(trie[tmp][j]){
if(tmp == )
fair[trie[tmp][j]] = ;
else {
p = fair[tmp];
while(p){
if(trie[p][j]){
fair[trie[tmp][j]] = trie[p][j];
break;
}
else p = fair[p];
}
if(!p) fair[trie[tmp][j]] = ;
}
q.push(trie[tmp][j]);
}
}
}
}
int Find(int len){
int ret = , rt = ;
for(int i = ; i < len; i++){
int id = str[i] - 'A';
while(rt != && !trie[rt][id]) rt = fair[rt];;
if(trie[rt][id]) rt = trie[rt][id];
int p = rt;
while(p != ){
if(cnt[p] >= ){
ret += cnt[p];
cnt[p] = -;
}
else break;
p = fair[p];
}
}
rt = ;
for(int i = len - ; i >= ; i--){
int id = str[i] - 'A';
while(rt != && !trie[rt][id]) rt = fair[rt];
if(trie[rt][id]) rt = trie[rt][id];
int p = rt;
while(p != ){
if(cnt[p] >= ){
ret += cnt[p];
cnt[p] = -;
}
else break;
p = fair[p];
}
}
return ret;
}
int main(){
int t;
scanf("%d", &t);
while(t--){
int n;
init();
scanf("%d", &n);
while(n--){
scanf("%s", str);
Insert();
}
Build_tree();
scanf("%s", tmp);
int len = strlen(tmp);
int ccc = ;
for(int i = ; i < len; i++){
if(tmp[i] != '['){
str[ccc++] = tmp[i];
}
else {
int _c = ;
i++;
while(isdigit(tmp[i]))
_c = _c * + (int)(tmp[i]-''), i++;
while(_c--)
str[ccc++] = tmp[i];
i++;
}
}
printf("%d\n", Find(ccc));
}
return ;
}

最新文章

  1. DOM对象模型接口规范中的四个基本接口
  2. Asp.net下使用HttpModule模拟Filter,实现权限控制
  3. cocos2dx 3.x(精灵的碰撞检测,点击移动与拖动精灵)
  4. PostgreSQL Cascade Replication
  5. IIS 7.5站点配置
  6. Macbook之用brew安装Python
  7. Discuz!NT 后台任意文件上传的源代码修补方法
  8. ORACLE 11G用于有效期
  9. asp.net中的绝对路径和相对路径
  10. linux问题: 切换用户之后变成-bash-4.1$
  11. String.split()分割字符串
  12. 广搜:codevs-3344(初步bfs)
  13. HTTPS的内网访问和访问外网
  14. HTTP Error 500.22 - Internal Server Error 错误解决方案
  15. [转] 怎么减少编程中的 bug?
  16. Python之路----列表推导式和生成器的表达式
  17. GCC参数详解 一
  18. 【Loadrunner】通过loadrunner录制时候有事件但是白页无法出来登录页怎么办?
  19. mongodb的存储引擎
  20. qq浏览器如何全屏截图

热门文章

  1. 携程酒店DevOps测试实践
  2. 开始使用Github
  3. js中的基本类型和引用类型
  4. 热更新,App双开,App隐藏,App试用 -- Replugin的实际应用(原创)
  5. 02ARM体系结构
  6. Spring Boot 2.x基础教程:使用MyBatis访问MySQL
  7. PAT-进制转换
  8. Windows Server 2012搭建SQL Server Always On踩坑全记录
  9. VUE实现Studio管理后台(一):鼠标拖放改变窗口大小
  10. PHP网络爬虫实践:抓取百度搜索结果,并分析数据结构