• 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
    ",Get_Ans());
    }
    
    int main()
    {
    	init();
    	work();
    	return 0;
    }
    
    由于博主比较菜,所以有很多东西待学习,大部分文章会持续更新,另外如果有出错或者不周之处,欢迎大家在评论中指出!
  • 相关阅读:
    hashlib模块
    configparser模块
    xml模块和shelve模块
    json与pickle模块
    3/30
    os模块
    sys模块
    shutil模块
    random模块
    2月书单《编码隐匿在计算机软硬件背后的语言》 13-16章
  • 原文地址:https://www.cnblogs.com/With-penguin/p/13289760.html
Copyright © 2020-2023  润新知