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
    */
    
  • 相关阅读:
    Nginx 部署多个 web 项目(虚拟主机)
    Nginx 配置文件
    Linux 安装 nginx
    Linux 安装 tomcat
    Linux 安装 Mysql 5.7.23
    Linux 安装 jdk8
    Linux 安装 lrzsz,使用 rz、sz 上传下载文件
    springMVC 拦截器
    spring 事务
    基于Aspectj 注解实现 spring AOP
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/9278688.html
Copyright © 2011-2022 走看看