Bzoj4516:[Sdoi2016]生成魔咒:哈希表+后缀自动机

来源:互联网 发布:淘宝美工主要做什么 编辑:程序博客网 时间:2024/05/17 07:32

题目链接:4516:[Sdoi2016]生成魔咒

裸sam,但是显然要用hash,于是我在sam里套了个hashset,交的时候总感觉内存虚虚的,还怕RE……

不过还好直接AC辣~\(≧▽≦)/~

#include<cstdio>#include<vector>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#define LL long longusing namespace std;const int maxn=150010;const int maxb=50;const int mod=41;int n; LL ans=0;inline int read(){int ret=0; char ch=getchar();for(;ch<'0'||ch>'9';ch=getchar());for(;ch>='0'&&ch<='9';ch=getchar())ret=ret*10+ch-'0'; return ret;}struct hashset{int next[maxb],val[maxb],As[maxb];int h[mod],tot;void init(){tot=0; memset(h,0,sizeof(h));}void push(int x,int id){int now=x%mod; if (now<0) now+=mod;for (int i=h[now];i;i=next[i])    if (val[i]==x) return;++tot; next[tot]=h[now]; h[now]=tot;val[tot]=x; As[tot]=id; return;}int find(int x){int now=x%mod; if (now<0) now+=mod;for (int i=h[now];i;i=next[i])    if (val[i]==x) return As[i];return -1;}void repush(int x,int id){int now=x%mod; if (now<0) now+=mod;for (int i=h[now];i;i=next[i])    if (val[i]==x){As[i]=id;return;}}}son[maxn];struct suffix_automation{int fa[maxn];int l[maxn],last,tot,root;void init(){tot=0; last=root=++tot;}int add(int x){int p=last,np=++tot; last=np; l[np]=l[p]+1; while (p&&son[p].find(x)==-1) son[p].push(x,np),p=fa[p];if (!p) fa[np]=root;else{int q=son[p].find(x);if (l[q]==l[p]+1) fa[np]=q;else{int nq=++tot; fa[nq]=fa[q]; l[nq]=l[p]+1;for (int i=1;i<=son[q].tot;++i){son[nq].next[i]=son[q].next[i];son[nq].As[i]=son[q].As[i];son[nq].val[i]=son[q].val[i];}for (int i=0;i<mod;++i) son[nq].h[i]=son[q].h[i];son[nq].tot=son[q].tot; fa[q]=fa[np]=nq;while (son[p].find(x)==q) son[p].repush(x,nq),p=fa[p];}}return l[np]-l[fa[np]];}}sam;int main(){sam.init();scanf("%d",&n); int x;for (int i=1;i<=n;++i)    printf("%lld\n",ans+=sam.add(x=read()));}


1 3
原创粉丝点击