SAM 20pts 求助
查看原帖
SAM 20pts 求助
357163
shyr楼主2022/8/9 20:09
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline int read(){
    int x = 0,f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9'){
        if(ch == '-')
            f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9'){
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    return x * f;
}
int n;
char s[100005]; 
template<class T, int MaxN> struct suffix_automaton{
	struct SAM{
		int len, fail, c[26];
	}d[MaxN * 2];
	vector<int> D[MaxN * 2];
	int tot = 0, lst = 0, rd[MaxN * 2], dp[MaxN * 2];
	suffix_automaton(){
		memset(d, 0, sizeof(d));
		memset(rd, 0, sizeof(rd));
		memset(dp, 0, sizeof(dp));
	} 
	void rebuild(){
		d[1].fail = 0;
		d[1].len = 0;
		tot++;
		lst = 1;
	}
	void insert(T x){
		int p = lst;
		int cur = ++tot;
		d[cur].len = d[p].len + 1;
		while(p && !d[p].c[x]){
			d[p].c[x] = cur;
			p = d[p].fail;
		}
		if(!p) d[cur].fail = 1;
		else{
			int q = d[p].c[x];
			if(d[q].len == d[p].len + 1) d[cur].fail = q;
			else{
				int clone = ++tot;
				d[clone].len = d[p].len + 1;
				d[clone].fail = d[q].fail;
				for(int i = 0; i <= 25; ++i) d[clone].c[i] = d[q].c[i];
				while(p && d[p].c[x]){
					d[p].c[x] = clone;
					p = d[p].fail;
				}
				d[q].fail = d[cur].fail = clone;
			}
		}
	//	printf("%d %d\n", cur, d[cur].fail);
		lst = cur; 
	}
	void calc(){
		ll ans = 0;
		for(int i = 1; i <= tot; ++i){
		//	printf("%d %d %d %d\n", i, d[i].len, d[i].fail, d[d[i].fail].len);
			ans += d[i].len - d[d[i].fail].len;
		}
		printf("%lld\n", ans);
	}
};
suffix_automaton<char, 100005> Suf;
int main(){
	n = read();
	scanf("%s", s + 1);
	Suf.rebuild();
	for(int i = 1; i <= n; ++i) Suf.insert(s[i] - 'a');
	Suf.calc();
	return 0;
}

2022/8/9 20:09
加载中...