题目大意:依次向字符串末尾加上一个字符,每次求不同子串个数
题解:SAM模板题,上map就不怕字符集问题了
SA也可以做,不过麻烦一些
注意SAM点数2n
我的收获:SAM+map解决字符集大小问题
#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
using namespace std;
const int N=200005;
int n,tot=1,root=1,last=1;
int fail[N],step[N];
long long ans;
map<int,int> ch[N];
int calc(int x){return step[x]-step[fail[x]];}
void add(int c){
int np=++tot,p=last;last=np;
step[np]=step[p]+1;
for(;p&&!ch[p][c];p=fail[p]) ch[p][c]=np;
if(!p) fail[np]=root; else{
int q=ch[p][c];
if(step[p]+1==step[q]) fail[np]=q; else{
int nq=++tot;step[nq]=step[p]+1;ch[nq]=ch[q];
fail[nq]=fail[q];fail[np]=fail[q]=nq;
for(;ch[p][c]==q;p=fail[p]) ch[p][c]=nq;
}
}
ans+=calc(np);
}
void init()
{
scanf("%d",&n);
for(int x,i=1;i<=n;i++)
{
scanf("%d",&x);
add(x);
printf("%lld\n",ans);
}
}
int main()
{
init();
return 0;
}
本文介绍了一种使用后缀自动机(SAM)解决字符串问题的方法,并通过一个具体的编程实例展示了如何利用SAM算法来计算随着字符串逐步增长过程中不同子串的数量变化。采用map解决了字符集大小的问题,提高了算法的通用性。
555

被折叠的 条评论
为什么被折叠?



