hdu6138 Fleet of the Eternal Throne AC自动机
来源:互联网 发布:数据网络开关在那 编辑:程序博客网 时间:2024/06/08 13:14
题目:给你n个字符串,m个询问,问x,y这两个字符串的最长子串,并且这个子串也是某个字符串的前缀。
思路:AC自动机,n个串插入自动机中,在用x串跑一遍自动机,把经过的点标记下来,再用y串跑一遍,看这个点是否走过,走过的话,就有可能成为答案。
代码:
#pragma comment(linker, "/STACK:1024000000,1024000000")#include<iostream>#include<algorithm>#include<cstdio>#include<cmath>#include<cstring>#include<string>#include<vector>#include<map>#include<set>#include<queue>#include<stack>#include<list>#include<numeric>using namespace std;#define LL long long#define ULL unsigned long long#define INF 0x3f3f3f3f#define mm(a,b) memset(a,b,sizeof(a))#define PP puts("*********************");template<class T> T f_abs(T a){ return a > 0 ? a : -a; }template<class T> T gcd(T a, T b){ return b ? gcd(b, a%b) : a; }template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}// 0x3f3f3f3f3f3f3f3f// 0x3f3f3f3fconst int SIGMA_SIZE = 26;const int MAXNODE = 2e5+50;const int maxn=2e5+50;int ch[MAXNODE][SIGMA_SIZE];int f[MAXNODE];// fail函数int dep[MAXNODE];int vis[MAXNODE];int sz;void AC_init(){ sz=1; mm(ch[0],0); mm(vis,0); dep[0]=0;}// 字符c的编号int idx(char c){ return c-'a';}// 插入字符串。v必须非0void AC_insert(char *s){ int u=0,n=strlen(s); for(int i=0;i<n;i++){ int c=idx(s[i]); if(!ch[u][c]){ mm(ch[sz],0); vis[sz]=0; dep[sz]=dep[u]+1; ch[u][c]=sz++; } u=ch[u][c]; }}// 计算fail函数void AC_getFail(){ queue<int>q; f[0]=0; // 初始化队列 for(int c=0;c<SIGMA_SIZE;c++){ int u=ch[0][c]; if(u){ f[u]=0;q.push(u); } } // 按BFS顺序计算fail while(!q.empty()){ int r=q.front();q.pop(); for(int c=0;c<SIGMA_SIZE;c++){ int u=ch[r][c]; //if(!u) continue; if(!u){//将不存在的边不上,这是为了将所有的转移一视同仁 ch[r][c]=ch[f[r]][c];continue; } q.push(u); int v=f[r]; while(v&&!ch[v][c]) v=f[v]; f[u]=ch[v][c]; } }}int AC_find(char *T,int now){ int n=strlen(T); int j=0;// 当前结点编号,初始为根结点 for(int i=0;i<n;i++){// 文本串当前指针 int c=idx(T[i]); //while(j&&!ch[j][c]) j=f[j];// 顺着失配边走,直到可以匹配 j=ch[j][c]; int tmp=j; while(tmp){ vis[tmp]=now;// printf("%d ",tmp); tmp=f[tmp]; } }// printf("\n");}int AC_Query(char *T,int now){ int n=strlen(T); int j=0;// 当前结点编号,初始为根结点 int ans=0; for(int i=0;i<n;i++){// 文本串当前指针 int c=idx(T[i]); //while(j&&!ch[j][c]) j=f[j];// 顺着失配边走,直到可以匹配 j=ch[j][c]; int tmp=j; while(tmp){ if(vis[tmp]==now){ ans=max(ans,dep[tmp]); }// printf("%d ",tmp); tmp=f[tmp]; } }// printf("\n"); return ans;}char s[maxn];int pos[maxn];int main(){ int T,n,m,x,y; scanf("%d",&T); while(T--){ AC_init(); int d=0; scanf("%d",&n); for(int i=0;i<n;i++){ pos[i]=d; scanf("%s",s+d); AC_insert(s+d); d+=strlen(s+d)+1; } AC_getFail(); scanf("%d",&m); int now=0; while(m--){ scanf("%d%d",&x,&y);x--;y--; now++; AC_find(s+pos[x],now); int ans=AC_Query(s+pos[y],now); printf("%d\n",ans); } } return 0;}
阅读全文
0 0
- hdu6138 Fleet of the Eternal Throne AC自动机
- HDU6138 Fleet of the Eternal Throne
- 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自动机)
- HDU 6138 Fleet of the Eternal Throne(AC自动机)
- HDU 6138 Fleet of the Eternal Throne AC自动机
- HDU 6138 2017多校第八场1006 Fleet of the Eternal Throne :AC自动机
- HDU 6138 Fleet of the Eternal Throne AC自动机||后缀数组
- HDU 6138 Fleet of the Eternal Throne 多校#8 AC自动机
- HDU 6138 Fleet of the Eternal Throne 多校#8 AC自动机
- HDU_6138 Fleet of the Eternal Throne 【AC自动机&&思维】【静态数组】
- HDU6138 F Fleet of the Eternal Throne(字典树+后缀数组+二分)
- HDU 6138 Fleet of the Eternal Throne
- hdu 6138 Fleet of the Eternal Throne
- HDU 6138 Fleet of the Eternal Throne
- C++基础
- C++基础2
- 链接脚本
- 关键路径详解
- noip2009 最优贸易
- hdu6138 Fleet of the Eternal Throne AC自动机
- 计算机网络基础概要
- Python3之爬虫爬取豆瓣读书Top250
- js实现li排序
- 双色球组合
- hdu 6156 Palindrome Function
- ELF
- JUnit单元测试
- Linux系统网络属性和基本配置