BZOJ 4516: [Sdoi2016]生成魔咒

来源:互联网 发布:get it hot 编辑:程序博客网 时间:2024/05/22 14:16

裸的SAM。。。。。。。

考察点是啥?SAM的复杂度是O(n)而不是O(n*sigma)?

#include<cstdio>#include<iostream>#include<cstring>#include<cmath>#include<queue>#include<vector>#include<algorithm>#include<map>#define rep(i,l,r) for(int i=l;i<=r;i++)#define per(i,r,l) for(int i=r;i>=l;i--)#define mmt(a,v) memset(a,v,sizeof(a))#define tra(i,u) for(int i=head[u];i;i=e[i].next)using namespace std;typedef long long ll;const int N=100000+5;map<int,int>go[N<<1];int par[N<<1],len[N<<1],sz,last,root;ll ans;int calc(int x){if(!par[x])return 0;return len[x]-len[par[x]];}void init(){root=last=++sz;}void extend(int x){int p=last,np=++sz;len[np]=len[p]+1;for(;p&&!go[p].count(x);p=par[p])go[p][x]=np;if(!p)par[np]=root;else{int q=go[p][x];if(len[q]==len[p]+1)par[np]=q;else{int nq=++sz;len[nq]=len[p]+1;go[nq]=go[q];par[nq]=par[q];ans-=calc(q);par[q]=par[np]=nq;ans+=calc(q)+calc(nq);for(;p&&go[p][x]==q;p=par[p])go[p][x]=nq;}}ans+=calc(np);last=np;}int main(){//freopen("a.in","r",stdin);int n;scanf("%d",&n);init();rep(i,1,n){int x;scanf("%d",&x);extend(x);printf("%lld\n",ans);}return 0;}



0 0
原创粉丝点击