HDU 6138 2017多校第八场1006 Fleet of the Eternal Throne :AC自动机
2017-08-17 18:39
483 查看
题意:给出n(<=1e5)个串(总长度<=1e5),以及q(<=300,数据有点弱,q改成1e5才好)次询问,每次询问给出x和y,表示输入的第x个和第y个串,要求找出一个最长的字串p,满足:p是x的字串,p是y的字串,且p是这n个串中某一个(可以是多个)的前缀,输出这个最大的长度。
题解:对n个串造出 自动AC机 ,这里的AC机不需要维护单词的结束点 需要维护一个每个节点到根的距离,也就是前缀的长度。然后用x跑一遍AC机,在所有匹配成功的结束节点上记上一个标记(直接记成询问次数就行了:第一次询问flag记成1,第二次记成2,这样保证每次的flag都不一样就不用清空标记了),然后这些标记点的意思就是:这个前缀是n个串中某个的前缀,且这个前缀是串x的字串。然后再用y跑一次AC机,在y匹配成功的节点,如果他刚刚被打了标记,那就统计最长的length就可以。
十分钟手切的自动AC机,在剩下最后五分钟的时候,过了样例就直接交了,然后队友一直在刷新Ranklist,突然发现A了。。。妈耶。。这太惊悚了有木有
Code:
题解:对n个串造出 自动AC机 ,这里的AC机不需要维护单词的结束点 需要维护一个每个节点到根的距离,也就是前缀的长度。然后用x跑一遍AC机,在所有匹配成功的结束节点上记上一个标记(直接记成询问次数就行了:第一次询问flag记成1,第二次记成2,这样保证每次的flag都不一样就不用清空标记了),然后这些标记点的意思就是:这个前缀是n个串中某个的前缀,且这个前缀是串x的字串。然后再用y跑一次AC机,在y匹配成功的节点,如果他刚刚被打了标记,那就统计最长的length就可以。
十分钟手切的自动AC机,在剩下最后五分钟的时候,过了样例就直接交了,然后队友一直在刷新Ranklist,突然发现A了。。。妈耶。。这太惊悚了有木有
Code:
#include<bits/stdc++.h> using namespace std; const int MAX = 100005; struct AC{ AC* nxt[26]; AC* fail; int length; int flag; }; AC* root; int n,q,ans; int index[MAX]; char allchar[MAX*10]; void clear(AC* node){ for (int i=0;i<=25;i++){ if (node->nxt[i]!=NULL){ clear(node->nxt[i]); } } free(node); } AC* create(){ AC* node = (AC*)(malloc(sizeof(AC))); memset(node->nxt,0,sizeof(node->nxt)); node->fail = NULL; node->flag = -1; node->length =0; return node; } AC* insert(AC* root,char* word){ AC* node = root; char* p = word; while (*p){ // cout<<*p<<endl; int id = *p-'a'; if (node->nxt[id]==NULL){ node->nxt[id]= create(); } node->nxt[id]->length = node->length+1; node = node->nxt[id]; p ++; } } void init(){ if (root!=NULL){ clear(root); } root = create(); } void input(){ scanf("%d",&n); int delta = 0; for (int i=1;i<=n;i++){ index[i] = delta; scanf("%s",allchar+delta); insert(root,allchar+delta); delta+=strlen(allchar+delta)+1; } } AC* que[MAX*10]; void build(){ int l=0; int r=1; que[1]= root; root->fail = root; while (l<r){ l++; AC* q = que[l]; for (int i=0;i<=25;i++){ if (q->nxt[i]!=NULL){ if (q==root){ q->nxt[i]->fail = root; }else{ q->nxt[i]->fail = q->fail; while (q->nxt[i]->fail->nxt[i]==NULL&&q->nxt[i]->fail!=root){ q->nxt[i]->fail = q->nxt[i]->fail->fail; } if (q->nxt[i]->fail->nxt[i]!=NULL){ q->nxt[i]->fail = q->nxt[i]->fail->nxt[i]; } } r++; que[r] = q->nxt[i]; } } } } void search(char * word,int f){ AC* node = root; char* p = word; while (*p){ // cout<<*p<<endl; int id = *p-'a'; while (node!=root&&node->nxt[id]==NULL){ node = node->fail; } if (node->nxt[id]!=NULL){ node = node->nxt[id]; } AC* temp = node; while (temp!=root){ temp->flag = f; temp = temp->fail; } p++; } } void query(char * word,int f){ AC* node = root; char* p = word; while (*p){ // cout<<*p<<endl; int id = *p-'a'; while (node!=root&&node->nxt[id]==NULL){ node = node->fail; } if (node->nxt[id]!=NULL){ node = node->nxt[id]; } AC* temp = node; while (temp!=root){ if (temp->flag ==f){ ans = max(ans,temp->length); } temp = temp->fail; } p++; } } void solve(){ scanf("%d",&q); for (int i=1;i<=q;i++){ int x,y; scanf("%d%d",&x,&y); search(allchar+index[x],i); ans =0; query(allchar+index[y],i); printf("%d\n",ans); } } int main(){ int t; scanf("%d",&t); while (t--){ init(); input(); build(); solve(); } }
相关文章推荐
- hdu 6138 Fleet of the Eternal Throne(AC自动机)
- HDU 6138 Fleet of the Eternal Throne(AC自动机)
- hdu 6138 Fleet of the Eternal Throne (ac自动机)
- HDU 6138 Fleet of the Eternal Throne(AC自动机)
- HDU 6138 Fleet of the Eternal Throne (AC自动机)
- 2017多校第8场 HDU 6138 Fleet of the Eternal Throne 思维,暴力
- hdu 6138 Fleet of the Eternal Throne
- HDU 6138 Fleet of the Eternal Throne (2017多校8 - AC自动机)
- HDU 6138 Fleet of the Eternal Throne(2017 Multi-University Training Contest 8)
- (后缀数组/Trie)HDU 6138-Fleet of the Eternal Throne
- HDU-2017 多校训练赛8-1006-Fleet of the Eternal Throne
- HDU 6138 Fleet of the Eternal Throne 多校#8 AC自动机
- HDU 6138 Fleet of the Eternal Throne
- HDU 6138 Fleet of the Eternal Throne 后缀数组 + 二分
- HDU 6138 Fleet of the Eternal Throne (后缀数组+字典树, 2017 Multi-Univ Training Contest 8)
- HDU 6138 Fleet of the Eternal Throne [AC自动机]
- hdu 6138 Fleet of the Eternal Throne 基于kmp算法的求解
- HDU 6138 Fleet of the Eternal Throne AC自动机||后缀数组
- HDU 6138 Fleet of the Eternal Throne ( AC自动机)
- 2017 Multi-University Training Contest - Team 8:Fleet of the Eternal Throne(AC自动机)