震撼
查看原帖
震撼
821939
zhi_hui_kan_ti_jie楼主2023/6/2 16:23

我写了份很胡扯的代码,就是二分答案后的结果+1,然后过了 我二分答案的check函数哪写错了

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
const int maxn = 1e6 + 10;
int s[maxn];
int sa[maxn], rk[maxn], ht[maxn];
int x[maxn], y[maxn], c[maxn];
int arr[maxn];
inline int min(int a, int b){ return a < b ? a : b; }
inline int max(int a, int b){ return a > b ? a : b; }
void buildsa(int n, int m = 3000) // nlogn
{//m字符集大小 n长度
	s[n] = 0; //*用来处理溢出问题
	for (int i = 0; i < m; i++)
		c[i] = 0;
	for (int i = 0; i < n; i++)
		c[x[i] = s[i]]++;
	for (int i = 1; i < m; i++)
		c[i] += c[i - 1];
	for (int i = n - 1; i >= 0; i--)
		sa[--c[x[i]]] = i;
	// 利用基数排序离散化
	for (int k = 1; k < n; k <<= 1){
		int p = 0;
		for (int i = n - 1; i >= n - k; i--)
			y[p++] = i;
		for (int i = 0; i < n; i++)
		if (sa[i] >= k)
			y[p++] = sa[i] - k;
		// 先利用第二位关键字排序
		for (int i = 0; i < m; i++)
			c[i] = 0;
		for (int i = 0; i < n; i++)
			c[x[y[i]]]++;
		for (int i = 1; i < m; i++)
			c[i] += c[i - 1];
		for (int i = n - 1; i >= 0; i--)
			sa[--c[x[y[i]]]] = y[i];
		// 以上为基数排序
		for (int j = 0; j <= n; j++)
			swap(x[j], y[j]);
		p = 1;
		x[sa[0]] = 0;
		y[n] = -1;
		for (int i = 1; i < n; i++)
		if (y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k])
		{
			x[sa[i]] = p - 1;
		}
		else
			x[sa[i]] = p++;
		if (p == n)
			break;
		m = p;
	}
	for (int i = 0; i < n; i++)
		rk[sa[i]] = i;
	//ht数组构造
	int k = 0;
	for (int i = 0; i < n; i++) // O(n)
	{ // ht[i]=lcp(sa[i],sa[i-1]);
		k = max(k - 1, 0ll);//保证复杂度,因为k每次k最多变小1
		if (rk[i] == 0)
			continue;
		int j = sa[rk[i] - 1];//他前面一个rk的字符串起始位置
		while ((i + k < n && j + k < n) && s[i + k] == s[j + k])
			k++;//最大为len
		ht[rk[i]] = k; // 对字符串第i个位置求其ht
	}
}
int xx;
int len, k;
int cnt;
int col[maxn];

bool check(int mid,int cnt,int n)
{
	int tmp[1010];
	memset(tmp, 0, sizeof(tmp));
	int vaild = 0;
	int sz = 1;
	for (int i = 1; i < cnt; i++)
	{
		if (ht[i] >= mid && ht[i - 1] >= mid)
		{
			if (tmp[col[sa[i]]] < sz)vaild++;
			if (tmp[col[sa[i - 1]]] < sz)vaild++;
			tmp[col[sa[i]]] = sz; tmp[col[sa[i-1]]] = sz;
		}
		else if (ht[i] >= mid && (i == 1 || ht[i - 1] < mid))
		{
			sz++;
			vaild = 0;
			if (tmp[col[sa[i]]] < sz)vaild++;
			if (tmp[col[sa[i-1]]] < sz)vaild++;
			tmp[col[sa[i]]] = sz; tmp[col[sa[i-1]]] = sz;
		}
		if (vaild == n) return true;
	}
	return false;
}
int ta[maxn];
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin >> n;
	int sz = 1865;
	for (int i = 1; i <= n; i++)
	{
		int m; cin >> m;
		for (int j = 0; j < m; j++)
		{
			cin >> ta[j];
		}
		for (int j = cnt+1; j < cnt + m; j++)
		{
			s[j] = ta[j-cnt] - ta[j - cnt - 1];
		}
		s[cnt] = 0;
		cnt += m;
		s[cnt++] = sz++;
	}
	buildsa(cnt);
	int tmp = 0;
	for (int i = 0; i < cnt; i++)
	{
		if (s[i]>1864)tmp++;
		col[i] = tmp;
	}
	int l = 1, r = 101;
	int ans;
	//for (int i = 101; i >= 1; i--)
	//{
	//	if (check(i, cnt, n))
	//	{
	//		cout << i;
	//		return 0;
	//	}
	//}
	while (l <= r)
	{
		int mid = l + r >> 1;
		if (check(mid,cnt,n))
		{
			ans = mid;
			l = mid + 1;
		}
		else
		{
			r = mid - 1;
		}
	}
	cout << ans+1;
	return 0;
}


2023/6/2 16:23
加载中...