luogu P2852 [USACO06DEC]Milk Patterns G

容易发现这就是后缀排序后连续 \(k\) 个后缀的 \(lcp\) 的最小值的最大值,用单调队列跑一遍 \(height\) 数组即可。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<deque>

using namespace std;

const int N=20009;
deque <int> q;
int n,k,a[N],b[N],m;
struct Suffix_Array
{
	int s[N],x[N],y[N],c[N],sa[N],height[N],h[N],n,m;
	
	void Rsort()
	{
		for (int i=1;i<=m;i++) c[i]=0;
		for (int i=1;i<=n;i++) c[x[y[i]]]++;
		for (int i=1;i<=m;i++) c[i]+=c[i-1];
		for (int i=n;i>=1;i--) sa[c[x[y[i]]]--]=y[i];
	}
	
	void Get_SA()
	{
		m=122;
		for (int i=1;i<=n;i++)
			x[i]=s[i],y[i]=i;
		Rsort();
		for (int k=1;k<=n;k<<=1)
		{
			int num=0;
			for (int i=n-k+1;i<=n;i++)
				y[++num]=i;
			for (int i=1;i<=n;i++)
				if(sa[i]>k)
					y[++num]=sa[i]-k;
			Rsort(),swap(x,y);
			x[sa[1]]=num=1;
			for (int i=2;i<=n;i++)
				x[sa[i]]=(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k])?num:++num;
			if(num==n) break;
			m=num;
		}
	}
	
	void Get_Height()
	{
		for (int i=1;i<=n;i++)
		{
			int t=max(h[i-1]-1,0),j,k;
			for (j=i+t,k=sa[x[i]-1]+t;s[j]==s[k]&&j<=n&&k<=n;j++,k++);
			h[i]=j-i;
		}
		for (int i=1;i<=n;i++)
			height[i]=h[sa[i]];
	}
	
	void work()
	{
		Get_SA(),Get_Height();
	}
}A;

void init()
{
	scanf("%d %d",&n,&k);
	for (int i=1;i<=n;i++)
		scanf("%d",&a[i]),b[i]=a[i];
	sort(b+1,b+1+n);
	m=unique(b+1,b+1+n)-(b+1);
	for (int i=1;i<=n;i++)
		a[i]=lower_bound(b+1,b+1+m,a[i])-b;
}

int Get_Ans()
{
	if(k==1) return n;
	if(k>n) return 0;
	k--;
	for (int i=2;i<=k+1;i++)
	{
		while(!q.empty()&&A.height[i]<=A.height[q.back()])
			q.pop_back();
		q.push_back(i);
	}
	int ans=A.height[q.front()];
	for (int i=k+2;i<=n;i++)
	{
		while(!q.empty()&&i-q.front()>=k)
			q.pop_front();
		while(!q.empty()&&A.height[i]<=A.height[q.back()])
			q.pop_back();
		q.push_back(i);
		ans=max(ans,A.height[q.front()]);
	}
	return ans;
}

void work()
{
	A.n=n;
	for (int i=1;i<=n;i++)
		A.s[i]=a[i];
	A.work();
	printf("%d\n",Get_Ans());
}

int main()
{
	init();
	work();
	return 0;
}
posted @ 2020-07-12 20:37  With_penguin  阅读(142)  评论(0编辑  收藏  举报