【SDOI2016】bzoj4516 生成魔咒【解法一】
2017-04-28 18:00
260 查看
每次在SAM中加入一个字符,维护每个点的vali−valfaili即可。
因为字符集很大,离散化以后也开不下,可以用map存转移。
因为字符集很大,离散化以后也开不下,可以用map存转移。
#include<cstdio> #include<map> #include<algorithm> using namespace std; #define LL long long const int maxn=200010; map<int,int> trans[maxn]; int fail[maxn],val[maxn],n,tot=1; void check() { for (int i=1;i<=tot;i++) for (map<int,int>::iterator it=trans[i].begin();it!=trans[i].end();++it) printf("%d-%d->%d\n",i,(*it).first,(*it).second); } int main() { LL ans=0; int last=1,p,np,q,nq,x; scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%d",&x); p=last; val[last=np=++tot]=val[p]+1; while (p&&!trans[p].count(x)) { trans[p][x]=np; p=fail[p]; } if (!p) fail[np]=1,ans+=val[np]; else { q=trans[p][x]; if (val[q]==val[p]+1) fail[np]=q,ans+=val[np]-val[q]; else { val[nq=++tot]=val[p]+1; fail[nq]=fail[q]; fail[np]=fail[q]=nq; trans[nq]=trans[q]; while (p&&trans[p][x]==q) { trans[p][x]=nq; p=fail[p]; } ans+=val[np]-val[nq]; } } //if (i==5) check(); printf("%lld\n",ans); } }
相关文章推荐
- 【SDOI2016】bzoj4516 生成魔咒【解法二】
- [后缀数组 set] BZOJ 4516 [Sdoi2016]生成魔咒
- BZOJ4516 SDOI2016生成魔咒(后缀数组+平衡树)
- 【BZOJ4516】生成魔咒(SDOI2016)-后缀自动机+map
- [bzoj4516] [Sdoi2016]生成魔咒
- bzoj 4516 [Sdoi2016]生成魔咒 后缀自动机
- BZOJ4516 [Sdoi2016]生成魔咒 【后缀自动机】
- BZOJ 4516 [Sdoi2016]生成魔咒 ——后缀自动机
- [bzoj4516][Sdoi2016]生成魔咒——后缀自动机
- BZOJ 4516 [Sdoi2016]生成魔咒
- [BZOJ4516][SDOI2016]生成魔咒
- [BZOJ4516][Sdoi2016]生成魔咒(后缀数组+链表||后缀自动机)
- 【bzoj4516】[Sdoi2016]生成魔咒
- 【BZOJ 4516】生成魔咒
- 【bzoj4516】[Sdoi2016]生成魔咒 后缀自动机
- BZOJ 4516: [Sdoi2016]生成魔咒 后缀自动机
- BZOJ.4516.[SDOI2016]生成魔咒(后缀数组 RMQ)
- [BZOJ4516] [SDOI2016] 生成魔咒 - 后缀数组/后缀自动机
- [BZOJ4516][Sdoi2016]生成魔咒(后缀数组+set/后缀自动机)
- 【bzoj4516】 Sdoi2016—生成魔咒