博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[HEOI2012]旅行问题 AC 自动机
阅读量:5086 次
发布时间:2019-06-13

本文共 1279 字,大约阅读时间需要 4 分钟。

题意:

求两个字符串的最长公共后缀,使得该后缀是某个字符串的前缀。

 

题解:

直接利用 $fail$ 指针的定义即可。

相当于求自动机上两点的 LCA,好像倍增可以,怕炸空间就老老实实写树剖吧。

 

 

Code:

#include
#include
#include
#include
#include
#include
#define idx str[i]-'a'#define maxn 2000103#define root 1#define sigma 27#define mod 1000000007 #define ll long long using namespace std;void setIO(string a){ freopen((a+".in").c_str(),"r",stdin); } char arr[maxn];int ch[maxn<<1][sigma],pos[maxn<<1],fail[maxn<<1],nodes=1, p[maxn];int hash[maxn<<1],cnt;void insert(char str[],int id){ int n=strlen(str); int j=root; for(int i=0;i
Q;int dep[maxn], f[23][maxn];void getfail(){ dep[root]=0; for(int i=0;i
dep[b]) swap(a,b); if(dep[a]!=dep[b]) for(int i=22;i>=0;--i) if(dep[f[i][b]]>=dep[a]) b=f[i][b]; if(a==b) return hash[a]; for(int i=22;i>=0;--i) if(f[i][a]!=f[i][b]) a=f[i][a],b=f[i][b]; return hash[f[0][a]];}int main(){ //setIO("input"); int n; scanf("%d",&n); for(int i=1;i<=n;++i) { scanf("%s",arr),insert(arr,i); p[i]=strlen(arr); p[i]+=p[i-1]; } getfail(); int m; scanf("%d",&m); for(int cas=1;cas<=m;++cas){ int i,j,k,l; scanf("%d%d%d%d",&i,&j,&k,&l); int y=query(pos[p[k-1]+l],pos[p[i-1]+j]); printf("%d\n",y); } return 0;}

  

转载于:https://www.cnblogs.com/guangheli/p/9900548.html

你可能感兴趣的文章
lc 145. Binary Tree Postorder Traversal
查看>>
sublime 配置java运行环境
查看>>
在centos上开关tomcat
查看>>
重启rabbitmq服务
查看>>
正则表达式(进阶篇)
查看>>
无人值守安装linux系统
查看>>
【传道】中国首部淘宝卖家演讲公开课:农业本该如此
查看>>
jQuery应用 代码片段
查看>>
MVC+Servlet+mysql+jsp读取数据库信息
查看>>
黑马程序员——2 注释
查看>>
用OGRE1.74搭建游戏框架(三)--加入人物控制和场景
查看>>
转化课-计算机基础及上网过程
查看>>
android dialog使用自定义布局 设置窗体大小位置
查看>>
ionic2+ 基础
查看>>
互联网模式下我们更加应该“专注”
查看>>
myeclipse集成jdk、tomcat8、maven、svn
查看>>
查询消除重复行
查看>>
Win 10 文件浏览器无法打开
查看>>
HDU 1212 Big Number(C++ 大数取模)(java 大数类运用)
查看>>
-bash: xx: command not found 在有yum源情况下处理
查看>>