T1订正记-AC自动机-从树到图
AC自动机已经足够棒了。
但是,好像有时还是要TLE的。
一般的AC自动还是比较好,如果在某些情况下还是会被卡掉,像是这个水题
考试的感觉
我看到这个题后,我清清楚楚的知道,这是个AC自动机+栈。
经过一番努力,把AC自动机打了出来,然后略加修饰,把栈补在里面。
我一复制,一粘贴,更高兴(?)了,过样例了,噫,我要A了。
但是我又随便写了一坨字符进去,然后就,不对了~~~~~~
最后也没调出来,后来我想想,好像是没恢复搜索栈顶元素。
我太菜了。
---以上都是废话---
更改的过程
我T60之后,想了一会,去查了Trie图,但是比较难受。
后来是有大神告诉我,可以用简单的办法构建部分Tire图,优化后就可以AC惹
但是我囿于万恶的板子,一直TLE。
唔啊啊啊啊!
我改了一会,建好图,信心满满,然后又……T了?
后来我又想,又问了几个大佬「没有得到满意的答复」
最后我充满疑惑的看到了我的while,好像不是那么回事
void ffind(){
int j=;
ACauto *p=root;
sta[t++]=root;
while(st[j]){
int k=st[j]-'a';
while(p!=root && p->s[k]==NULL) p=p->next;
p=p->s[k];
sta[t++]=p;
if(p==NULL) p=root;
ACauto *l=p;
while(l!=root){//这个while
if(l->len!=){
t-=l->len;
p=sta[t-];
break;
}
l=l->next;
}
j++;
}
}
我为什么要反复去找一个字符呢?
于是删掉while,改成if,AC。
额,一个while卡我6000ms。
分析一下,
我写的板子来自上面的两道题,有重复字符,互为子串的也有
而本题明确说明:N个字符串中无互相包含的
所以这句话就是没有意义的,它反复去找出现这个字符的地方,浪费了众多时间
而我们只需要找上一个字符出现之后的这一个字符就可以
所以,改成if更加正确。
void ffind(){
int j=;
ACauto *p=root;
sta[t++]=root;
while(st[j]){
int k=st[j]-'a';
while(p!=root && p->s[k]==NULL) p=p->next;
p=p->s[k];
sta[t++]=p;
if(p==NULL) p=root;
ACauto *l=p;
if(l->len!=){
t-=l->len;
p=sta[t-];
}
j++;
}
}
全代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 101010
using namespace std;
struct ACauto{
ACauto *next,*s[];
int len;
char ch;
}s[*N];int tot=;
ACauto *newACauto(){
tot++;
return &s[tot-];
}
ACauto *root=newACauto();
char st[N],ch[N];
ACauto *q[];int f=,e=;
bool empty(){
if(f==e)return true;
return false;
}
void push(ACauto *x){
e++;
q[e]=x;
}
ACauto* front(){
f++;
return q[f];
}
void add(const char *c){
int j=;
ACauto *i=root;
while(c[j]){
int k=c[j]-'a';
if(i->s[k]==NULL) i->s[k]=newACauto();
i=i->s[k];
i->ch=c[j];
j++;
}
i->len=j;
}
void build(){
root->next=NULL;
push(root);
while(!empty()){
ACauto *n=front();
for(int i=;i<;i++){
if(n->s[i]!=NULL){
if(n==root) n->s[i]->next=root;
else{
ACauto *p=n->next;
while(p!=NULL){
if(p->s[i]!=NULL){
n->s[i]->next=p->s[i];
// n->s[i]=p;
break;
}
p=p->next;
}
if(p==NULL) n->s[i]->next=root;
}
push(n->s[i]);
}
else{
if(n==root)
n->s[i]=root;
else
n->s[i]=n->next->s[i];
}
}
}
}
ACauto *sta[N];
int t=;
void pour(){
for(int i=;i<t;i++){
putchar(sta[i]->ch);
}
puts("");
}
void ffind(){
int j=;
ACauto *p=root;
sta[t++]=root;
while(st[j]){
int k=st[j]-'a';
while(p!=root && p->s[k]==NULL) p=p->next;
p=p->s[k];
sta[t++]=p;
if(p==NULL) p=root;
ACauto *l=p;
if(l->len!=){
//pour();//cout<<t<<" "<<l->len<<endl;
t-=l->len;
p=sta[t-];
}
j++;
}
}
int _n=;
void prerun(){
for(int i=;i<;i++){
root->s[i]=new ACauto();
root->s[i]->ch='a'+i;
}
}
int main(){
prerun();
scanf("%s",st);
scanf("%d",&_n);
for(int i=;i<=_n;i++){
scanf("%s",ch);
add(ch);
}
build();
ffind();
for(int i=;i<t;i++)putchar(sta[i]->ch);
puts("");
return ;
}
>这里<
T1订正记-AC自动机-从树到图的更多相关文章
- hdu 4117 GRE Words (ac自动机 线段树 dp)
参考:http://blog.csdn.net/no__stop/article/details/12287843 此题利用了ac自动机fail树的性质,fail指针建立为树,表示父节点是孩子节点的后 ...
- hdu 4117 -- GRE Words (AC自动机+线段树)
题目链接 problem Recently George is preparing for the Graduate Record Examinations (GRE for short). Obvi ...
- 【BZOJ2434】阿狸的打字机(AC自动机,树状数组)
[BZOJ2434]阿狸的打字机(AC自动机,树状数组) 先写个暴力: 每次打印出字符串后,就插入到\(Trie\)树中 搞完后直接搭\(AC\)自动机 看一看匹配是怎么样的: 每次沿着\(AC\)自 ...
- 【BZOJ2434】【NOI2011】阿狸的打字机(AC自动机,树状数组)
[BZOJ2434]阿狸的打字机(AC自动机,树状数组) 先写个暴力: 每次打印出字符串后,就插入到\(Trie\)树中 搞完后直接搭\(AC\)自动机 看一看匹配是怎么样的: 每次沿着\(AC\)自 ...
- BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2545 Solved: 1419[Submit][Sta ...
- NOI 2011 阿狸的打字机(AC自动机+主席树)
题意 https://loj.ac/problem/2444 思路 多串匹配,考虑 \(\text{AC}\) 自动机.模拟打字的过程,先建出一棵 \(\text{Trie}\) 树,把它变成自动机 ...
- BZOJ2905: 背单词 AC自动机+fail树+线段树
$zjq$神犇一眼看出$AC$自动机 $Orz$ 直接就讲做法了 首先对每个串建出$AC$自动机 将$fail$树找到 然后求出$dfs$序 我们发现一个单词 $S_i$是$S_j$的子串当且仅当$S ...
- BZOJ 2905: 背单词 AC自动机+fail树+dfs序+线段树
Description 给定一张包含N个单词的表,每个单词有个价值W.要求从中选出一个子序列使得其中的每个单词是后一个单词的子串,最大化子序列中W的和. Input 第一行一个整数TEST,表示数据组 ...
- BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]
3172: [Tjoi2013]单词 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 3198 Solved: 1532[Submit][Status ...
随机推荐
- oracle报ORA-00911:invalid character
转自:http://www.cnblogs.com/chuang-sharing/p/9493316.html 今天查问题的时候,发现一个在分号后边加注释,解析错误的问题: select decode ...
- View Programming Guide for iOS ---- iOS 视图编程指南(四)---Views
Views Because view objects are the main way your application interacts with the user, they have many ...
- rbenv的使用
创建: 2017/09/05 更新: 2018/02/03 增加更新rbenv和获取list没有的版本 更新: 2018/02/25 把path里面[个人主机名]全部替换为[主机名] 更新: 2018 ...
- Codeforces Round #355 (Div. 2)C - Vanya and Label
啊啊啊啊啊啊啊,真的是智障了... 这种题目,没有必要纠结来源.只要知道它的结果的导致直接原因?反正这句话就我听的懂吧... ">>"/"&" ...
- U3D 的一些基础优化
1.在使用数组或ArrayList对象时应当注意 [csharp] view plaincopy length=myArray.Length; for(int i=0;i<length;i++) ...
- rpm -e ** error :No such file or directory 解决
参考文章:http://www.redhat.com/archives/rpm-list/2006-June/msg00025.html 我遇到的情况是这样的: 1 先安装包 rpm -ivh tes ...
- springboot修改项目不需要重启服务器
一.spring-boot-devtools 在pom中直接引入依赖 <dependency> <groupId>org.springframework.boot ...
- UVa 12186 Another Crisis 工人的请愿书
c表示某上司上报的最少请愿下属,k表示总下属c=0.01T*k=kT/100(0.01T*k是整数)c=[0.01T*k]+1=[kT/100]+1(0.01T*k不是整数) kT=100 c=1 k ...
- 水题 Codeforces Round #303 (Div. 2) A. Toy Cars
题目传送门 /* 题意:5种情况对应对应第i或j辆车翻了没 水题:其实就看对角线的上半边就可以了,vis判断,可惜WA了一次 3: if both cars turned over during th ...
- 转 多个版本的数据库在同一服务器上ORA-12557
http://blog.chinaunix.net/uid-42518-id-3153473.html 问题描述:当同一台机子上安装了多个版本的数据库,可能在连接库或ASM时会报以下错误.ORA-12 ...