• poj3261(后缀数组)


    题意:给出一串长度为n的字符,再给出一个k值,要你求重复次数大于等于k次的最长子串长度........

    思路:其实也非常简单,直接求出height值,然后将它分组,二分答案......结果就出来了.......

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    #define maxx 110000
    int wa[maxx],wb[maxx],wsf[maxx],wv[maxx];
    int sa[maxx],rank[maxx],s[maxx],height[maxx];
    struct node
    {
    	int num,x;
    }str[maxx];
    int cmp1(const node a,const node b)
    {
    	if(a.x<b.x)
    	return 1;
    	else
    	return 0;
    }
    int cmp(int *r,int a,int b,int k)
    {
    	return r[a]==r[b]&&r[a+k]==r[b+k];
    } 
    void getsa(int *r,int *sa,int n,int m)
    {
    	int i,j,p,*x=wa,*y=wb,*t;
    	for(i=0;i<m;i++)  wsf[i]=0;
    	for(i=0;i<n;i++)  wsf[x[i]=r[i]]++;
    	for(i=1;i<m;i++)  wsf[i]+=wsf[i-1];
    	for(i=n-1;i>=0;i--)  sa[--wsf[x[i]]]=i;
    	j=1;
    	p=1;
    	for(;p<n;j*=2,m=p)
    	{
    		for(p=0,i=n-j;i<n;i++)  y[p++]=i;
    		for(i=0;i<n;i++)  if(sa[i]>=j)  y[p++]=sa[i]-j;
    		for(i=0;i<n;i++)  wv[i]=x[y[i]];
    		for(i=0;i<m;i++)  wsf[i]=0;
    		for(i=0;i<n;i++)  wsf[wv[i]]++;
    		for(i=1;i<m;i++)  wsf[i]+=wsf[i-1];
    		for(i=n-1;i>=0;i--)  sa[--wsf[wv[i]]]=y[i];
    		t=x;
    		x=y;
    		y=t;
    		x[sa[0]]=0;
    		for(p=1,i=1;i<n;i++)   x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
    	}
    }
    void getheight(int *r,int *sa,int n)
    {
    	int i,j,k=0;
    	for(i=1;i<=n;i++)
    	rank[sa[i]]=i;
    	for(i=0;i<n;i++)
    	{
    		if(k)
    		k--;
    		else
    		k=0;
    		j=sa[rank[i]-1];
    		while(r[i+k]==r[j+k])
    		k++;
    		height[rank[i]]=k;
    	}
    }
    int deal(int n,int mid,int k)
    {
    	int flag=1;                     //要注意,初始值是1.....应该一个height值,是两个字符的lcp,i与i-1的....所以初始值应该从1开始.... 
    	for(int i=2;i<=n;i++)
    	{
    		if(height[i]>=mid)
    		{
    			flag++;
    			if(flag>=k)
    			return 1;
    		}
    		else  flag=1;
    	}
    	return 0;
    }
    int main()
    {
    	int n,k;
    	while(scanf("%d%d",&n,&k)>0)
    	{
    		int zd=0;
    		for(int i=0;i<n;i++)
    		{
    			scanf("%d",&str[i].x);
    			str[i].num=i;
    		}
    		sort(str,str+n,cmp1);
    		int j=1;
    		s[str[0].num]=j;
    		for(int i=1;i<n;i++)
    		{
    			if(str[i].x==str[i-1].x)
    			s[str[i].num]=j;
    			else
    			{
    				j++;
    				s[str[i].num]=j;
    			}
    		}
    		s[n]=0;
    		//for(int i=0;i<n;i++)
    		//printf("%d ",s[i]);
    		getsa(s,sa,n+1,j+10);
    		getheight(s,sa,n);
    		int left=0,right=n,count=0,mid;
    		while(left<=right)
    		{
    			mid=(left+right)/2;
    			if(deal(n,mid,k))
    			{
    				if(count<mid)
    				count=mid;
    				//printf("%d
    ",mid);
    				left=mid+1;
    			}
    			else  right=mid-1;
    		}
    		printf("%d
    ",count);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Python学习-day18 Web框架
    Python学习-day17 jQuery method and demo
    centos 7环境下安装rabbitmq
    linux java7升级到java8
    idea推送项目到github
    HttpServletRequest.getInputStream()多次读取问题
    spring boot 自动装配的原理
    mysql 的INNODB引擎和MYISAM引擎的区别、索引相关
    事务的传播性和隔离级别
    Atomic 的实现原理
  • 原文地址:https://www.cnblogs.com/ziyi--caolu/p/3195917.html
Copyright © 2020-2023  润新知