社区讨论

求解算法正确性

P3375【模板】KMP参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@locthwmh
此快照首次捕获于
2023/10/30 19:29
2 年前
此快照最后确认于
2023/11/05 06:08
2 年前
查看原帖
RT,用Z算法解border数组。方法是对于每个 ii,将 bord[i+zi1]bord[i+z_i-1] 赋值为 ziz_i,然后从后往前倒推(bord[i] = max(bord[i], bord[i + 1]))洛谷数据都过了,请问这个算法是否正确?
code:
CPP
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>

const int N = 1000000;

char a[N + 10], b[N + N + 10];
int z[N + N + 10];

void get_z(const char *str, const int len, int *arr) {
	int maxl = 0, maxr = 0;
	// [1, maxr - maxl + 1] = [maxl, maxr]
	// [i - maxl + 1, maxr - maxl + 1] = [i, maxr]
	arr[1] = len;
	for (int i = 2; i <= len; ++ i) {
		if (i <= maxr) {
			arr[i] = std::min(arr[i - maxl + 1], maxr - i + 1);
		}
		while (i + arr[i] <= len && str[arr[i] + 1] == str[i + arr[i]])
			++ arr[i];
		if (i + arr[i] - 1 > maxr) {
			maxr = i + arr[i] - 1;
			maxl = i;
		}
	}
	return;
}

int n, m;

int bord[N + 10];

int main() {
	scanf("%s%s", a + 1, b + 1);
	n = strlen(a + 1);
	m = strlen(b + 1);
	get_z(b, m, z);
//	for (int i = 1; i <= m; ++ i) {
//		printf("z[%d]=%d\n", i, z[i]);
//	}
	for (int i = m; i >= 2; -- i) {
		bord[i + z[i] - 1] = z[i];
	}
	for (int i = m - 1; i >= 1; -- i) {
		bord[i] = std::max(bord[i], bord[i + 1] - 1);
	}
	b[m + 1] = '#';
	for (int i = 1; i <= n; ++ i) {
		b[m + 1 + i] = a[i];
	}
	get_z(b, m + 1 + n, z);
	for (int i = 1; i <= n; ++ i) {
		if (z[m + 1 + i] == m)
			printf("%d\n", i);
	}
	for (int i = 1; i <= m; ++ i) {
		printf("%d ", bord[i]);
	}
	printf("\n");
	return 0;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...