好好写一个带注释的回文树模板

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Cymbals/article/details/83019436

——我发现我快忘了QWQQQQQQ,赶紧整理一下。

struct Pam {
	int next[maxn][26];
	int fail[maxn];
	int len[maxn];// 当前节点表示回文串的长度
	int cnt[maxn];// 当前节点表示回文串的出现次数
	int num[maxn];// 到当前节点这里有多少本质不同的回文子串
	int S[maxn];
	int last, n, p;

	int newNode(int l) {
		memset(next[p], 0, sizeof(next[p]));
		len[p] = l;
		return p++;
	}

	void init() {
		n = last = p = 0;
		newNode(0);
		newNode(-1);
		S[n] = -1;
		fail[0] = 1;
	}

	int getFail(int x) {
		while(S[n - len[x] - 1] != S[n]) {
			x = fail[x];
		}
		return x;
	}

	void add(int c) {
		S[++n] = c;
		int cur = getFail(last);
		if(!next[cur][c]) {
			int now = newNode(len[cur] + 2);
			fail[now] = next[getFail(fail[cur])][c];
			next[cur][c] = now;
			num[now] = num[fail[now]] + 1;
		}
		last = next[cur][c];
		++cnt[last];
	}

	void update() {
		// 类似sam从后往前更新,回文树是一颗前缀树,当前回文串的出现必定伴随其前缀的出现
		for(int i = p - 1; i >= 0; i--) {
			cnt[fail[i]] += cnt[i];
		}
	}

	void build() {
		int lenn = strlen(s);
		for(int i = 0; i < lenn; i++) {
			add(s[i] - 'a');
		}
	}

} pam;

猜你喜欢

转载自blog.csdn.net/Cymbals/article/details/83019436
今日推荐