BZOJ 4516 [Sdoi2016]生成魔咒 ——后缀自动机
2017-03-01 22:59
543 查看
本质不同的字串,考虑SA的做法,比较弱,貌似不会。
好吧,只好用SAM了,由于后缀自动机的状态最简的性质,
所有不同的字串就是∑l[i]-l[fa[i]],
然后后缀自动机是可以在线的,然后维护一下就可以了。
#include <map> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define F(i,j,k) for (int i=j;i<=k;++i) #define D(i,j,k) for (int i=j;i>=k;--i) #define ll long long #define maxn 200005 inline int read() { int x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } struct Suffix_Automata{ map<int,int> go[maxn]; char s[maxn]; ll ans; int l[maxn],fa[maxn],last,cnt; void init(){last=cnt=1;} void add(int x) { int p=last,np=last=++cnt; l[np]=l[p]+1; for (;p&&!go[p][x];p=fa[p]) go[p][x]=np; if (!p) fa[np]=1; else { int q=go[p][x]; if (l[q]==l[p]+1) fa[np]=q; else { int nq=++cnt; 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; } } ans+=l[last]-l[fa[last]]; } void solve() { init(); int n; ans=0; n=read(); F(i,1,n) { int x; x=read(); add(x); printf("%lld\n",ans); } } }sam; int main(){sam.solve();}
相关文章推荐
- BZOJ.4516.[SDOI2016]生成魔咒(后缀自动机 map)
- bzoj 4516 [Sdoi2016]生成魔咒 后缀自动机
- [BZOJ4516][Sdoi2016]生成魔咒(后缀数组+链表||后缀自动机)
- BZOJ 4516: [Sdoi2016]生成魔咒 后缀自动机
- [BZOJ4516] [SDOI2016] 生成魔咒 - 后缀数组/后缀自动机
- BZOJ4516 [Sdoi2016]生成魔咒 后缀自动机
- BZOJ 4516: [Sdoi2016]生成魔咒 [后缀自动机]
- BZOJ4516 [Sdoi2016]生成魔咒 【后缀自动机】
- 【bzoj4516】[Sdoi2016]生成魔咒 后缀自动机
- bzoj 4516: [Sdoi2016]生成魔咒 (后缀自动机)
- [bzoj4516][Sdoi2016]生成魔咒——后缀自动机
- [BZOJ4516][SDOI2016]生成魔咒(后缀自动机)
- [BZOJ4516][Sdoi2016]生成魔咒(后缀数组+set/后缀自动机)
- [BZOJ4516][SDOI2016]生成魔咒(后缀自动机)
- BZOJ.4516.[SDOI2016]生成魔咒(后缀数组 RMQ)
- 【BZOJ4516】【Sdoi2016】生成魔咒 后缀数组 线段树
- bzoj 4516: [Sdoi2016]生成魔咒 后缀数组
- BZOJ 4516: [Sdoi2016]生成魔咒
- BZOJ 4516: [Sdoi2016]生成魔咒
- BZOJ 4516: [Sdoi2016]生成魔咒——后缀数组、并查集