P4070 [SDOI2016] 生成魔咒
P4070 [SDOI2016] 生成魔咒
题目描述
魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示。例如可以将魔咒字符
一个魔咒串
例如
共进行
数据规模与约定
对于
说句闲话:
Solution:
十分模板的一道题,每加进来一个数字,我们就在 sam 上将其 insert 那么每次答案统计就是
Code:
#include<bits/stdc++.h> #define ll long long const int N=2e5+5; using namespace std; int n,m; ll ans; struct SAM{ map<int,int> ch[N]; int len[N],fa[N]; int last,cnt; void init(){last=cnt=1;} inline void insert(int c) { int p=last,q=++cnt;len[q]=len[p]+1;last=q; for(;p&&!ch[p][c];p=fa[p])ch[p][c]=q; if(!p){fa[q]=1;return;}int x=ch[p][c]; if(len[x]==len[p]+1){fa[q]=x;return;} int y=++cnt;len[y]=len[p]+1;fa[y]=fa[x];ch[y]=ch[x]; for(;p&&ch[p][c]==x;p=fa[p])ch[p][c]=y; fa[x]=fa[q]=y; } inline void calc(){ans+=len[last]-len[fa[last]];} }sam; void work() { cin>>n; sam.init(); for(int i=1,x;i<=n;i++) { scanf("%d",&x); sam.insert(x);sam.calc(); printf("%lld\n",ans); } } int main() { //freopen("incantation.in","r",stdin);freopen("incantation.out","w",stdout); work(); return 0; }