zoukankan      html  css  js  c++  java
  • P2408 不同子串个数(后缀自动机)

    建出link树后,每个节点的len[i]-len[link[i]]就是它所代表的不同子串数量。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=4e6+10;
    int len[maxn],link[maxn],nxt[maxn][26];
    int sz[maxn];
    int tot=1,lst=1;
    string s;
    int n;
    void sam_extend (char c) {
    	int cur=++tot;
    	len[cur]=len[lst]+1;
    	sz[cur]=1;
    	int p=lst;
    	while (p&&!nxt[p][c-'a']) {
    		nxt[p][c-'a']=cur;
    		p=link[p];
    	}
    	if (!p) {
    		link[cur]=1;
    	}
    	else {
    		int q=nxt[p][c-'a'];
    		if (len[p]+1==len[q]) {
    			link[cur]=q;
    		}
    		else {
    			int clone=++tot;
    			len[clone]=len[p]+1;
    			for (int i=0;i<26;i++) {
    				nxt[clone][i]=nxt[q][i];
    			}
    			link[clone]=link[q];
    			while (p&&nxt[p][c-'a']==q) {
    				nxt[p][c-'a']=clone;
    				p=link[p];
    			}
    			link[q]=link[cur]=clone;
    		}
    	}
    	lst=cur;
    }
    vector<int> g[maxn];
    void dfs (int u) {
    	for (int v:g[u]) {
    		dfs(v);
    	}
    }
    int main () {
    	cin>>n;
    	cin>>s;
    	for (char i:s) sam_extend(i);
    	long long ans=0;
    	for (int i=2;i<=tot;i++) ans+=len[i]-len[link[i]];
    	printf("%lld
    ",ans); 
    }
  • 相关阅读:
    ACM 一种排序
    ACM Binary String Matching
    ACM 括号配对问题
    ACM BUYING FEED
    ACM 喷水装置(二)
    ACM 会场安排问题
    ACM 推桌子
    ACM 心急的C小加
    ACM 田忌赛马
    ACM 疯牛
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/15015723.html
Copyright © 2011-2022 走看看