社区讨论

hack

P3975[TJOI2015] 弦论参与者 2已保存回复 1

讨论操作

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

当前回复
1 条
当前快照
1 份
快照标识符
@ly9u8jst
此快照首次捕获于
2024/07/06 16:03
2 年前
此快照最后确认于
2024/07/06 17:48
2 年前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;
char s[N];
int n, k, type;
int sa[N], rk[N], h[N], id[N], cnt[N], oldrk[N];
void build_SA()
{
	int m = 128;
	for(int i = 1; i <= n; i++) cnt[rk[i] = s[i]]++;
	for(int i = 1; i <= m; i++) cnt[i] += cnt[i - 1];
	for(int i = n; i; i--) sa[cnt[rk[i]]--] = i;
	for(int w = 1, p; w <= n; w <<= 1, m = p)
	{
		memset(cnt, 0, sizeof(cnt)); int cur = 0;
		for(int i = n - w + 1; i <= n; i++) id[++cur] = i;
		for(int i = 1; i <= n; i++)
			if(sa[i] > w) id[++cur] = sa[i] - w;
		for(int i = 1; i <= n; i++) cnt[rk[i]]++;
		for(int i = 1; i <= m; i++) cnt[i] += cnt[i - 1];
		for(int i = n; i; i--) sa[cnt[rk[id[i]]]--] = id[i];
		memcpy(oldrk, rk, (n + 1) * sizeof(int)); p = 0;
		for(int i = 1; i <= n; i++)
		{
			if(oldrk[sa[i]] != oldrk[sa[i - 1]] || oldrk[sa[i] + w] != oldrk[sa[i - 1] + w]) p++;
			rk[sa[i]] = p;
		}
		if(p == n) break;
	}
	// for(int i = 1; i <= n; i++) cout << rk[i] << ' ';
	// cout << '\n';
	for(int i = 1, k = 0; i <= n; i++)
	{
		if(k) k--;
		while(s[i + k] == s[sa[rk[i] - 1] + k]) k++;
		h[rk[i]] = k;
	}
}
int main()
{
	cin >> s + 1;
	cin >> type >> k;
	n = strlen(s + 1);
	build_SA();
	if(type == 0)
	{
		for(int i = 1; i <= n; i++)
		{
			int ct = (n - sa[i] + 1) - h[i];
			if(k <= ct)
			{
				for(int j = sa[i]; j - sa[i] - h[i] + 1 <= k; j++)
					cout << s[j];
				return 0;
			}
			k -= ct;
		}
	}
	else
	{
		for(int i = 1; i <= n; i++)
		{
			for(int j = h[i] + 1; j <= n - sa[i] + 1; j++)
			{
				int l = i; k--;
				while(k && l < n && h[l + 1] >= j) l++, k--;
				if(!k)
				{
					for(int l = sa[i]; l - sa[i] < j; l++)
						cout << s[l];
					return 0;
				}
			}
		}
	}
	cout << -1;
	return 0;
}
这份代码可以通过此题,但是显然在 type=1\text{type=1}
while(k && l < n && h[l + 1] >= j) l++, k--;一行的复杂度是完全错误的,只需要构造一个所有字符都相同的串就能卡掉。

回复

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

正在加载回复...