提交记录 19987


用户 题目 状态 得分 用时 内存 语言 代码长度
Min_25 1006. 【模板题】后缀排序 Accepted 100 7.415 ms 4140 KB C++ 3.41 KB
提交时间 评测时间
2023-08-22 09:03:35 2023-08-22 09:03:39
#include <cstdio>
#include <algorithm>
#include <numeric>
#include <cassert>
#include <cstring>

struct IO_Tp
{
	const static int _O_Buffer_Size = 2 << 20;
	char _O_Buffer[_O_Buffer_Size], *_O_pos = _O_Buffer;
	
	~IO_Tp() { fwrite(_O_Buffer, 1, _O_pos - _O_Buffer, stdout); }
	
	IO_Tp &operator<<(int n)
	{
		static char _buf[10];
		char* _pos = _buf;
		do
			*_pos++ = '0' + n % 10;
		while (n /= 10);
		while (_pos != _buf)
			*_O_pos++ = *--_pos;
		return *this;
	}
	
	IO_Tp &operator<<(char ch)
	{
		*_O_pos++ = ch;
		return *this;
	}
} IO;

const int Max_N = 100005;

namespace SA_IS
{
	int *sa;
	
	template<typename _Char>
	void sais_core(const int n, const int m, const _Char s[], char type[], int lms[], int cnt[])
	{
		int n1 = -1;
		
		type[n] = 1;
		for (int i = n - 1; i >= 0; --i)
		{
			type[i] = s[i] == s[i + 1] ? type[i + 1] : s[i] < s[i + 1];
			if (type[i] == 0 && type[i + 1] == 1)
				type[i + 1] = 2, lms[++n1] = i + 1;
		}
		std::reverse(lms, lms + n1 + 1);
		
		std::fill(cnt, cnt + m, 0);
		for (int i = 0; i <= n; ++i)
			++cnt[static_cast<int>(s[i])];
		std::partial_sum(cnt, cnt + m, cnt);
		
		auto induced_sort = [&](const int v[])
		{
			std::fill(sa, sa + n + 1, 0);
			
			int *cur = cnt + m;
			auto push_S = [&](const int x) { sa[--cur[static_cast<int>(s[x])]] = x; };
			auto push_L = [&](const int x) { sa[cur[static_cast<int>(s[x])]++] = x; };
			
			std::copy(cnt, cnt + m, cur);
			for (int i = n1; i >= 0; --i)
				push_S(v[i]);
			
			std::copy(cnt, cnt + m - 1, cur + 1);
			for (int i = 0; i <= n; ++i)
				if (sa[i] > 0 && type[sa[i] - 1] == 0)
					push_L(sa[i] - 1);
			
			std::copy(cnt, cnt + m, cur);
			for (int i = n; i >= 0; --i)
				if (sa[i] > 0 && type[sa[i] - 1])
					push_S(sa[i] - 1);
		};
		
		induced_sort(lms);
		
		auto lms_equal = [&](int x, int y)
		{
			if (s[x] == s[y])
				while (s[++x] == s[++y])
					if (type[x] == 2)
						return true;
			return false;
		};
		
		int ch = -1;
		
		int *s1 = std::remove_if(sa, sa + n, [&](const int x) { return type[x] != 2; });
		for (int i = 0; i <= n1; ++i)
			s1[sa[i] >> 1] = ch += ch <= 0 || !lms_equal(sa[i], sa[i - 1]);
		for (int i = 0; i <= n1; ++i)
			s1[i] = s1[lms[i] >> 1];
		
		if (ch < n1)
			sais_core(n1, ch + 1, s1, type + n + 1, lms + n1 + 1, cnt + m);
		else
			for (int i = 0; i <= n1; ++i)
				sa[s1[i]] = i;
		
		auto tmp = lms + n1 + 1;
		for (int i = 0; i <= n1; ++i)
			tmp[i] = lms[sa[i]];
		induced_sort(tmp);
	}
	
	template<typename _Char>
	void main(const _Char s[], const int n, const int m)
	{
		static int _lms[Max_N], _cnt[Max_N << 1];
		static char _type[Max_N << 1];
		
		/*
		for (int i = 0; i != n; ++i)
			assert(1 <= s[i] && s[i] < m);
		assert(s[n] == 0);
		*/
		
		sais_core(n, m, s, _type, _lms, _cnt);
	}
}

template<typename _Char>
void klaap(const _Char s[], const int sa[], int lcp[], const int n)
{
	static int rk[Max_N];
	for (int i = 0; i < n; ++i)
		rk[sa[i]] = i;
	for (int i = 0, h = lcp[0] = 0; i < n; ++i)
		if (h -= h != 0, rk[i])
		{
			for (int j = sa[rk[i] - 1]; i + h < n && j + h < n && s[i + h] == s[j + h]; ++h)
				;
			lcp[rk[i]] = h;
		}
}

int main(int argc, char **argv)
{
	static char s[Max_N];
	static int sa[Max_N], lcp[Max_N];
	
	scanf("%s", s);
	int N = strlen(s);
	
	SA_IS::sa = sa;
	SA_IS::main(s, N, 128);
	klaap(s, sa + 1, lcp, N);
	
	for (int i = 1; i <= N; ++i)
		IO << sa[i] + 1 << " \n"[i == N];
	for (int i = 1; i < N; ++i)
		IO << lcp[i] << " \n"[i == N];
	if (N == 1)
		IO << '\n';
	
	return 0;
}

CompilationN/AN/ACompile OKScore: N/A

Subtask #1 Testcase #113.83 us56 KBAcceptedScore: 0

Subtask #1 Testcase #216.64 us56 KBAcceptedScore: 100

Subtask #1 Testcase #316.17 us56 KBAcceptedScore: 0

Subtask #1 Testcase #414.8 us56 KBAcceptedScore: 0

Subtask #1 Testcase #514.52 us56 KBAcceptedScore: 0

Subtask #1 Testcase #614.87 us56 KBAcceptedScore: 0

Subtask #1 Testcase #76.48 ms3 MB + 324 KBAcceptedScore: 0

Subtask #1 Testcase #87.415 ms3 MB + 508 KBAcceptedScore: 0

Subtask #1 Testcase #97.357 ms3 MB + 296 KBAcceptedScore: 0

Subtask #1 Testcase #104.683 ms2 MB + 160 KBAcceptedScore: 0

Subtask #1 Testcase #114.747 ms2 MB + 208 KBAcceptedScore: 0

Subtask #1 Testcase #124.88 ms3 MB + 632 KBAcceptedScore: 0

Subtask #1 Testcase #134.962 ms3 MB + 568 KBAcceptedScore: 0

Subtask #1 Testcase #144.722 ms3 MB + 124 KBAcceptedScore: 0

Subtask #1 Testcase #154.784 ms3 MB + 168 KBAcceptedScore: 0

Subtask #1 Testcase #165.353 ms4 MB + 44 KBAcceptedScore: 0

Subtask #1 Testcase #175.318 ms3 MB + 1000 KBAcceptedScore: 0

Subtask #1 Testcase #185.231 ms4 MBAcceptedScore: 0


Judge Duck Online | 评测鸭在线
Server Time: 2024-11-22 18:52:42 | Loaded in 1 ms | Server Status
个人娱乐项目,仅供学习交流使用 | 捐赠