MAXimal

���������: 7 Sep 2008 14:40
�������������: 24 Aug 2011 18:36

���������� [������]

������������ �������. �������� ������. ���������� ����������� ������������ ������

������� ������������ �������

��������� ������� ������������ ������� (Lyndon decomposition).

������ ���������� �������, ���� ��� ������ ������ ������ ������ ������������ ��������. ������� ������� �����: a, b, ab, aab, abb, ababb, abcd. ����� ��������, ��� ������ �������� ������� ����� � ������ �����, ����� ��� ������ ������ ���� ����� ������������� ����������� �������.

�����, ����� ���� ������ s. ����� ������������� ������� ������ s ���������� � ���������� s = w_1 w_2 \ldots w_k, ��� ������ w_i ������, � ��� ���� w_1 \ge w_2 \ge \ldots \ge w_k.

����� ��������, ��� ��� ����� ������ s ��� ���������� ���������� � �����������.

�������� ������

�������� ������ (Duval's algorithm) ������� ��� ������ ������ ����� n ������������ ������� �� ����� O (n) � �������������� O (1) �������������� ������.

�������� �� �������� ����� � 0-����������.

����� ��������������� ������� ����������� ������. ������ t ���������� �����������, ���� ��� ����� ��� t = w w w \ldots w \overline{w}, ��� w — ��������� ������� ������, � \overline{w} — ��������� ������� ������ w.

�������� ������ �������� ������. � ����� ������ ��� ������ ������ S ���������� ��������� �� ��� ������ s = s_1 s_2 s_3, ��� � ������ s_1 ������������ ������� ��� ������� � s_1 ��� ������ �� ������������ ����������; ������ s_2 — ��� ����������� ������ (������ ����� ������� ����� ������ �� �� ����� ����������); ������ s_3 — ��� ��� �� ������������ ����� ������ s. ������ ��� �������� ������ ���� ������ ������ ������ s_3 � �������� �������� ��� � ������ s_2. ��� ����, ��������, ��� ������-�� �������� ������ s_2 ������������ ������� ���������� ���������, � ��� ����� ��������� � ������ s_1.

������ ������ �������� ���������. ��-������, ����� �������������� ��������� i �� ������ ������ s_2. ������� ���� ��������� ����� �����������, ���� i < n, �.�. ���� ��� ������ s �� ������� � ������ s_1. ������ ����� ����� ��������� ��� ���������: ��������� j �� ������ ������ s_3 (���������� ��������� �� ��������� ������-��������) � ��������� k �� ������� ������ � ������ s_2, � ������� ����� ������������� ���������. ����� ����� � ����� �������� �������� ������ s[j] � ������ s_2, ��� ���� ���������� ���������� ��������� � �������� s[k]. ����� � ��� ��������� ��� ��������� ������:

  • ���� s[j] = s[k], �� �� ����� �������� ������ s[j] � ������ s_2, �� ������� � "������������". �������������, � ���� ������ �� ������ ����������� ��������� j � k �� �������.

  • ���� s[j] > s[k], ��, ��������, ������ s_2 + s[j] ������ �������. ����� �� ����������� j �� �������, � k ����������� ������� �� i, ����� ��������� ������ ����������� � ������ �������� s_2.

  • ���� s[j] < s[k], �� ������ s_2+s[j] ��� �� ����� ���� �����������. ������� �� ��������� ����������� ������ s_2 �� ������� ������ ���� "�������" (������� ������� ������, ��������, ������); ������� ������ ��������� � ����� (�.�. ������� �� �������, ������� ���������� ��������� i), � "�������" ������ � �������� s[j] ��������� ������� � ������ s_3, � ������������� ���������� ����������� �����. ��� ����� �� �� ��������� �������� �������� ����� ������ ���������� �������, ����, ��� �� �� ��� ���������� ����������� ������ � ����������� �������� ��������. �������� ������ ��������, ��� ��� ������ ������� ������� ����� ��� ����� ����� �� �����; �� ���, ��������, ����� j-k.

����������

������� ���������� ��������� ������, ������� ����� �������� ������� ������������ ������� ������ s:

string s; // ������� ������
int n = (int) s.length();
int i=0;
while (i < n) {
	int j=i+1, k=i;
	while (j < n && s[k] <= s[j]) {
		if (s[k] < s[j])
			k = i;
		else
			++k;
		++j;
	}
	while (i <= k) {
		cout << s.substr (i, j-k) << ' ';
		i += j - k;
	}
}

�����������

����� �������, ��� ��� ��������� ������ ��������� O (1) ������, � ������ ��� ��������� i, j, k.

������ ������ ����� ������ ���������.

������� ���� while ������ �� ����� n ��������, ��������� � ����� ������ ��� �������� ��������� ��� ������� ���� ������ (� ����� �������� ���������, ��������, ����� n).

������ ������ ���������� �������� ������� ���������� ����� while. ��� ����� ���������� ������ ��������� ���� while — �� ��� ������ ���� ������� ������� ��������� ���������� r \ge 1 ����� ����� � ��� �� ������� ������ ��������� ����� p = j-k. �������, ��� ������ s_2 �������� �����������, ������ � ������� ������ ����� ����� ��� ��� p, �.�. � ����� �� ����������� r p + p - 1. ��������� ����� ������ s_2 ����� j-i, � ��������� j ������������� �� ������� �� ������ �������� ������� ���������� ����� while, �� ���� ���� �������� �� ����� r p + p - 2 ��������. ������ ������� �������� ������ r = 1, � �� ��������, ��� ������ ��������� ���� while ������ ��� ��������� �� ����� 2 p - 2 ��������. ���������, ��� ����� ��������� n ��������, ��������, ��� ��� ������ n �������� ��������� �� ����� 2 n - 2 �������� ������� ���������� while-�.

�������������, �������� ������ ����������� �� O (n).

����� ������� � ����� ��������� ��������, ����������� ���������� ������. ��������� ������ �������� ������� ���������� ����� while ���������� ��� ��������� ��������, � ����� ���� ��������� ������������ ����� ��������� �������� ����� (����� ������, ��� ���� ������ ������������), �� ����� ����� ��������� �������� �� ����������� 4 n - 3.

���������� ����������� ������������ ������

����� ���� ������ s. �������� ��� ������ s+s ������������ ������� (�� ����� ��� ������� �� O (n) ������� � O (1) ������ (���� �� ��������� ������������ � ����� ����)). ����� ����������� ����, ������� ���������� � �������, ������� n (�.�. � ������ ���������� ������ s), � ������������� � �������, ������� ��� ������ n (�.�. �� ������ ����������). ������������, ��� ������� ������ ����� ����� � ����� ������� �������� ������������ ������ (� ���� ����� ���������, ���������������� ������������ ������������ �������).

������ ������������ ����� ����� ������ — ���������� ��������, ��� ��������� i � ������ ������ �������� �������� ����� while ��������� �� ������ �������� ������������ �����.

����� �� �������� ����� ���������� (��� ��������� ���� ��� ���������� O (n) ������, ����� ������� ��������� ������ � ����):

string min_cyclic_shift (string s) {
	s += s;
	int n = (int) s.length();
	int i=0, ans=0;
	while (i < n/2) {
		ans = i;
		int j=i+1, k=i;
		while (j < n && s[k] <= s[j]) {
			if (s[k] < s[j])
				k = i;
			else
				++k;
			++j;
		}
		while (i <= k)  i += j - k;
	}
	return s.substr (ans, n/2);
}

������ � online judges

������ �����, ������� ����� ������, ��������� �������� ������: