zoukankan      html  css  js  c++  java
  • P2852 [USACO06DEC]牛奶模式Milk Patterns

    link

    这是一道后缀匹配的模板题

    我们只需要将height算出来

    然后二分一下答案就可以了

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int maxn=1010000;
    int data[maxn];
    int rank[maxn];
    int tot[maxn];
    int sa[maxn];
    int pas[maxn];
    int len,n,m;
    int height[maxn];
    int k;
    void build_Sa()
    {
    	m=150;
    	for(int i=0;i<n;i++)
    		rank[i]=data[i],tot[data[i]]+=1;
    	for(int i=1;i<=m;i++)
    		tot[i]+=tot[i-1];
    	for(int i=n-1;i>=0;i--)
    		sa[--tot[rank[i]]]=i;
    	for(int k=1;k<=n;k<<=1)
    	{
    		int num=0;
    		for(int i=n-k;i<n;i++)	pas[num++]=i;
    		for(int i=0;i<n;i++)
    			if(sa[i]>=k)	pas[num++]=sa[i]-k;
    		for(int i=0;i<=m;i++)	tot[i]=0;
    		for(int i=0;i<n;i++)	tot[rank[i]]+=1;
    		for(int i=1;i<=m;i++)	tot[i]+=tot[i-1];
    		for(int i=n-1;i>=0;i--)
    			sa[--tot[rank[pas[i]]]]=pas[i],pas[i]=0;
    		swap(pas,rank);
    		num=1;rank[sa[0]]=1;
    		for(int i=1;i<n;i++)
    			if(pas[sa[i]]!=pas[sa[i-1]]||pas[sa[i]+k]!=pas[sa[i-1]+k])		
    				rank[sa[i]]=++num;
    			else
    				rank[sa[i]]=num;
    		if(num>=n)	break;
    		m=num;
    	}
    }
    void build_LCP()
    {
    	int h=0;
    	/*for(int i=0;i<n;i++)	pas[sa[i]]=i;
    	for(int i=0;i<n;i++)
    	{
    		if(!pas[i])	continue;
    		int j=sa[pas[i]-1];
    		if(h)	h--;
    		while(data[j+h]==data[i+h]&&j+h<n&&i+h<n)	h++;
    		height[pas[i]]=h;
    	}*/
    	for(int i=0;i<n;i++)
    	{
    		if(rank[i]-1==0)	continue;
    		int j=sa[rank[i]-2];
    		if(h)	h-=1;
    		while(j+h<n&&i+h<n)
    			if(data[j+h]!=data[i+h])	break;
    			else h+=1;
    		height[rank[i]]=h;
    	}
    }
    bool check(int val)
    {
    	int now=0;
    	for(int i=0;i<=n;i++)
    	{
    		if(height[i]>=val)	now+=1;
    		else	now=0;
    		if(now>=k-1)	return true;
    	}
    	return false;
    }
    int main()
    {
    	scanf("%d%d",&n,&k);
    	for(int i=0;i<n;i++)	scanf("%d",&data[i]);
    	int l=1,r=n,mid;
    	build_Sa();
    	build_LCP();
    	while(l+1<r)
    	{
    		mid=(l+r)>>1;
    		if(check(mid))	l=mid;
    		else r=mid-1;
    	}
    	printf("%d", check(r) ? r : l  );
    }
    /*
    8 2
    1
    2
    3
    2
    3
    2
    3
    1
    12323231
    */
    
  • 相关阅读:
    WCF系列(七) WCF安全系列(二) netTCPBinding绑定之Transport安全模式
    WCF系列(六) WCF安全系列(一) basicHttpBinding
    Convert .Net Program To Mono
    Adware:Win32/FastSaveApp 清除
    Python Http Get Post请求
    Python正则表达式应用示例
    Basic4android 使用Basic开发Android应用
    Decode Android AndroidManifest.xml file via C#
    Python工作记录
    趣文:程序员/开发人员的真实生活
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/9278688.html
Copyright © 2011-2022 走看看