后缀自动机初探
2016-02-05 10:59
281 查看
之前看过几次后缀自动机,然后因为人太蠢都没看懂。
最近重新填坑TAT。。。
BZOJ4032: [HEOI2015]最短不公共子串
建出后缀自动机和序列自动机,然后我们知道自动机上每一条路径都相当于一个子串(子序列),这样只要从根节点开始bfs一遍,找到A有而B没有的,那就是字典序最小的辣。
View Code
最近重新填坑TAT。。。
BZOJ4032: [HEOI2015]最短不公共子串
建出后缀自动机和序列自动机,然后我们知道自动机上每一条路径都相当于一个子串(子序列),这样只要从根节点开始bfs一遍,找到A有而B没有的,那就是字典序最小的辣。
#include<cstring> #include<iostream> #include<algorithm> #include<cstdio> #include<map> #include<cmath> #define rep(i,l,r) for (int i=l;i<=r;i++) #define down(i,l,r) for (int i=l;i>=r;i--) #define clr(x,y) memset(x,y,sizeof(x)) #define maxn 4005000 #define ll long long #define inf 1152921504606846976 #define mm 1000000007 #define low(x) x&(-x) using namespace std; struct data{int obj,pre; }e[maxn*2]; int n,c,tot,d[maxn],a[maxn],head[maxn]; ll read(){ ll x=0,f=1; char ch=getchar(); while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while (isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();} return x*f; } struct SAM{ int l[maxn],fa[maxn]; map<int,int> go[maxn]; int last,tot; void expand(int x){ int p,q,np,nq; p=last; if ((q=go[p][x])){ if (l[q]==l[p]+1) last=q; else { nq=++tot; l[nq]=l[p]+1; go[nq]=go[q]; fa[nq]=fa[q]; fa[q]=nq; for (;p&&go[p][x]==q;p=fa[p]) go[p][x]=nq; last=nq; } } else { np=++tot; l[np]=l[p]+1; for (;p&&!go[p][x];p=fa[p]) go[p][x]=np; if (!p) fa[np]=1; else { q=go[p][x]; if (l[q]==l[p]+1) fa[np]=q; else { nq=++tot; l[nq]=l[p]+1; go[nq]=go[q]; fa[nq]=fa[q]; fa[q]=fa[np]=nq; for (;p&&go[p][x]==q;p=fa[p]) go[p][x]=nq; } } last=np; } } }A; void insert(int x,int y){ e[++tot].obj=y; e[tot].pre=head[x]; head[x]=tot; d[x]++; e[++tot].obj=x; e[tot].pre=head[y]; head[y]=tot; d[y]++; } void dfs(int u,int f){ if (f==0) A.last=1; A.expand(a[u]); int now=A.last; for (int j=head[u];j;j=e[j].pre){ int v=e[j].obj; if (v!=f) dfs(v,u); A.last=now; } } int main(){ n=read(); c=read(); rep(i,1,n) a[i]=read(); A.tot=1; rep(i,1,n-1) { int x=read(),y=read(); insert(x,y); } rep(i,1,n) if (d[i]==1) {dfs(i,0);} ll ans=0; rep(i,1,A.tot) ans+=1LL*(A.l[i]-A.l[A.fa[i]]); printf("%lld\n",ans); return 0; }
View Code
相关文章推荐
- 文件上传之 commons-fileupload(一)
- 用 Python 开发网站自动化测试脚本
- android 屏幕自适应讲解
- JavaSE-网络编程
- 文件上传之 MultipartFile
- 两个DateTime变量无法相等
- 第4讲项目2——完成简单计算(3)
- doppia编译过程可能会遇到的问题
- EL表达式从数组 Map List集合取值
- Hadoop家族学习路线图(干货系列)
- Item 22: 当使用Pimpl机制时,在实现文件中给出特殊成员函数的实现
- Servlet监听器
- 分页技术框架(Pager-taglib)学习三(pager-taglib中传递参数时中文乱码问题)
- Item 21: 比起直接使用new优先使用std::make_unique和std::make_shared
- Item 20: 使用std::weak_ptr替换会造成指针悬挂的类std::shared_ptr指针
- 安装 Dubbo 管理控制台
- 分页技术框架(Pager-taglib)学习二(SSH数据库分页)
- Web连接cube,并将CellSet转成DataTable
- Ugly Windows
- Item 19: 使用srd::shared_ptr来管理共享所有权的资源