Palindrome automaton topics and common set of operations

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/qcwlmqy/article/details/99880443

Palindrome automata


With i i is a string of end node maintains

After adding a node

Is the palindromic sequence in the original all true suffix ( m a r k [ f a i l [ n in m ] ] mark[fail[num]]

Increasing a palindromic sequence update ( mark[num])

if (!tree[last][in[i] - 'a']) {
	/*operation*/
	mark[num] = mark[fail[num]] + 1;
    //统计以该节点为结尾的回文串个数
}
//更新last
cnt[i]=mark[last];

Palindrome automaton (PAM)

Interesting


The total number of strings of different nature

Is the number of nodes, blows 1No. Node

mark[i]=num-1

Palindromes and Super Abilities

CA Loves Palindromic


Maintaining essentially different character string (information from the sub-tree)

For a different nature string

His son can visit his tree

Mark all strings, all statistical information can he subtree

Due to the larger number, about the number of layers deep, so it can traverse backwards

for (int i = 1; i <= n; i++) {
	while (in[i - len[last] - 1] != in[i]) last = fail[last];
	if (!tree[last][in[i] - 'a']) {
		/*operation*/
	}
	last = tree[last][in[i] - 'a'];
	mark[last]++;	//标记信息
}
for (int i = num; i; i--) {
	mark[fail[i]] += mark[i];
    //统计子树信息
}

P3649 palindrome string

Cheerleading rehearsal


Maintain different nature palindrome string (information from the father, ancestor)

set up f a i l fail Tree

Use d f s dfs , maintenance information back palindromic sequence ancestry

void build() {
	memset(head, 0, sizeof(int) * (num + 1)); tot = 0;
	for (int i = 2; i <= num; i++) AddEdge(fail[i], i);
    //建树,用fail边建树
}
int vis[maxn],res[maxn];
void dfs(int now) {
	vis[len[now]]++;//维护祖先信息
    /*operation 统计答案*/
	for (int i = head[now]; i; i = edge[i].next)
		dfs(edge[i].v);	//dfs
	vis[len[now]]--;//回溯
	return;
}

HDU6599 I Love Palindrome String

Palindromeness


Maintenance information palindromic sequence has front and rear ends

The establishment of two palindromic sequence

Build a positive, forward, backwards build a

For inode maintains iinformation and node positive sequence palindromic sequence i+1descending node palindromic sequence information can be combined

struct PAM {
	int tree[maxn][26];
	int len[maxn], fail[maxn];
	int last, num , mark[maxn];
	void insert(char* in, int n) {
		/*operation*/
	}
}pre, suf;
int main() {
	scanf("%s", in + 1); in[0] = '#';
	int n = strlen(in + 1);
	pre.insert(in, n);
    //正向建立
	reverse(in + 1, in + 1 + n);
	suf.insert(in, n);
    //反向建立
	int ans = 0;
	for (int i = 1; i < n; i++) {
		ans = max(ans, pre.mark[i] + suf.mark[n-i]);
        //两个串信息合并
	}
}

P4287 double palindrome

Harry and magic string


Add front-end node

pre,lastAdd two markers before and after maintenance

With pre, for example, when you add a node after

When the string is not the longest palindrome itself after the new node, the node will not affect the newly addedlast

which is l e n [ l a s t ] f a i l [ l a s t ] len[last],fail[last] is the correct

After the new node itself longest palindrome string to be updatedlast

The update method is l a s t = p r e last=pre

Since only the statistical side, so we count the number of strings of different nature and number of the total of the string is correct

But maintain other information when needed serious consideration

The following is inserted forward:

Similar inserted backwards

void pre_insert(char* in, int i) {	//向前添加方法
	while (in[i + len[pre] + 1] != in[i]) pre = fail[pre];
	if (!tree[pre][in[i] - 'a']) {
		len[++num] = len[pre] + 2;
		int j = fail[pre];
		while (in[i + len[j] + 1] != in[i]) j = fail[j];
		fail[num] = tree[j][in[i] - 'a'];
		tree[pre][in[i] - 'a'] = num;
		mark[num] = mark[fail[num]] + 1;	//统计个数
	}
	pre = tree[pre][in[i] - 'a'];
	if (len[pre] == stdr - stdl + 1) last = pre;//当本身变为回文串,更新last
	sum = sum + mark[pre];	//维护总个数
}

Victor and String


To optimize the space before stars

As MLEbefore, we can use the star chain optimization

To create a dictionary tree star before that the use of chain

Query: traversing all sides, since each point in trie limited number of visits, the complex will not exceed

Assignment: that is built side

struct Edge{
	int v;
	int w;	//w为字母的值
	int next;
}edge[maxn];
int head[maxn], tot;
inline void AddEdge(int u, int v, int w) {
	edge[++tot].v = v;
	edge[tot].w = w;
	edge[tot].next = head[u];
	head[u] = tot;
}
int find(int now, int w) {	//寻找函数
	for (int i = head[now]; i; i = edge[i].next)
		if (edge[i].w == w) return edge[i].v;
	return 0;
}
for (int i = 1; i <= n; i++) {
	while (in[i - len[last] - 1] != in[i]) last = fail[last];
	int treenode = find(last, in[i] - 'a');//寻找节点
	if (!treenode) {
		len[++num] = len[last] + 2;
		int j = fail[last];
		while (in[i - len[j] - 1] != in[i]) j = fail[j];
		fail[num] = find(j, in[i] - 'a');//寻找节点
		AddEdge(last, num, in[i] - 'a');//建边
		mark[num] = mark[fail[num]] + 1;
		treenode = num;	//更新节点
	}
	last = treenode;
	cnt[i] = mark[last];
}

CF17E Palisection

Guess you like

Origin blog.csdn.net/qcwlmqy/article/details/99880443