[BZOJ4516][SDOI2016]生成魔咒
2018-03-27 21:17
453 查看
bzoj
luogu
\(n\le100000\),字符集大小\(10^9\)
每次插入以后,新增的贡献就是\(len[last]-len[fa[last]]\)。
累加即可。
luogu
题意
求一个串每个前缀中含有多少个不同字串\(n\le100000\),字符集大小\(10^9\)
sol
后缀自动机的转移开个\(map\)就好了。每次插入以后,新增的贡献就是\(len[last]-len[fa[last]]\)。
累加即可。
code
#include<cstdio> #include<algorithm> #include<map> using namespace std; int gi() { int x=0,w=1;char ch=getchar(); while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar(); if (ch=='-') w=0,ch=getchar(); while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return w?x:-x; } const int N = 2e5+5; int n,last=1,tot=1,fa ,len ;long long ans; map<int,int>tr ; void extend(int c) { int v=last,u=++tot;last=u; len[u]=len[v]+1; while (v&&!tr[v][c]) tr[v][c]=u,v=fa[v]; if (!v) fa[u]=1; else { int x=tr[v][c]; if (len[x]==len[v]+1) fa[u]=x; else { int y=++tot; tr[y]=tr[x]; fa[y]=fa[x];fa[x]=fa[u]=y;len[y]=len[v]+1; while (v&&tr[v][c]==x) tr[v][c]=y,v=fa[v]; } } } int main() { n=gi(); for (int i=1;i<=n;++i) { int x=gi(); extend(x); printf("%lld\n",ans+=len[last]-len[fa[last]]); } return 0; }
相关文章推荐
- 【BZOJ 4516】【SDOI 2016】生成魔咒
- [BZOJ4516][Sdoi2016]生成魔咒(后缀数组+set/后缀自动机)
- 【bzoj4516】 Sdoi2016—生成魔咒
- 【bzoj4516】[Sdoi2016]生成魔咒
- BZOJ 4516: [Sdoi2016]生成魔咒
- BZOJ 4516 [Sdoi2016]生成魔咒 ——后缀自动机
- 【bzoj4516】[Sdoi2016]生成魔咒 后缀自动机
- BZOJ 4516: [Sdoi2016]生成魔咒
- bzoj 4516: [Sdoi2016]生成魔咒 后缀数组
- [bzoj4516] [Sdoi2016]生成魔咒
- [bzoj4516] [Sdoi2016]生成魔咒
- bzoj 4516: [Sdoi2016]生成魔咒 后缀数组
- ●BZOJ 4516 [Sdoi2016]生成魔咒
- [BZOJ4516][SDOI2016]生成魔咒(后缀自动机)
- BZOJ4516 [Sdoi2016]生成魔咒 【后缀自动机】
- [BZOJ4516][Sdoi2016]生成魔咒(后缀数组+链表||后缀自动机)
- bzoj 4516: [Sdoi2016]生成魔咒
- BZOJ 4516: [Sdoi2016]生成魔咒 后缀自动机
- 【BZOJ4516】【SDOI2016】生成魔咒 [SAM]
- BZOJ 4516: [Sdoi2016]生成魔咒