cunzai_zsy0531

关注我

P2408 不同子串个数 题解

题面

每个点 \(u\) 代表 \(len_ u-len_{nxt_u}\) 这么多串。这个也可以 DAWG dp 求得,不过太麻烦了。

点击查看代码
const int N=1e5+13;
int n,nxt[N<<1],len[N<<1],lastpos=1,ptot=1;
char s[N];
std::unordered_map<int,int> son[N<<1],boom;
inline int newpos(std::unordered_map<int,int> nson,int nlen){return ++ptot,len[ptot]=nlen,std::swap(son[ptot],nson),ptot;}
inline void insert(int c){
	int p=lastpos;int u=newpos(boom,len[p]+1);
	while(p&&son[p].find(c)==son[p].end()) son[p][c]=u,p=nxt[p];
	lastpos=u;
	if(!p) return nxt[u]=1,void();
	int d=son[p][c];
	if(len[d]==len[p]+1) nxt[u]=d;
	else{
		int v=newpos(son[d],len[p]+1);
		nxt[v]=nxt[d],nxt[d]=nxt[u]=v;
		while(p&&son[p][c]==d) son[p][c]=v,p=nxt[p];
	}
}
int main(){
	read(n);read(s+1);
	for(int i=1;i<=n;++i) insert(s[i]-'a');
	ll ans=0;
	for(int i=2;i<=ptot;++i) ans+=len[i]-len[nxt[i]];
	println(ans);
	return 0;
}
posted @ 2022-05-18 20:46  cunzai_zsy0531  阅读(12)  评论(0编辑  收藏  举报