zoukankan      html  css  js  c++  java
  • 后缀数组模板 UOJ#35. 后缀排序

    从梓轩学姐提交记录那里搞来的,简单易懂,没有那些奇奇怪怪的东西...

    #include<cstdio>
    #include<cstring>
    const int MAXN=100000,D=50;
    int n,str[MAXN+D];
    int sa[MAXN+D],rank[MAXN+D],height[MAXN+D];
    int p[MAXN+D],temp[MAXN+D],cnt[MAXN+D];
    inline bool equ(int x,int y,int l){return rank[x]==rank[y]&&rank[x+l]==rank[y+l];}
    void init(){
    	char ch=getchar();
    	while(ch>='a'&&ch<='z')str[n++]=ch-'a',ch=getchar();
    }
    void doubling()
    {
    	str[n]=rank[n]=-1;
    	for(int i=0;i<n;i++)sa[i]=i,rank[i]=str[i];
    	for(int i,l=0,pos=0,sig=26;pos<n-1;sig=pos)
    	{
    		for(i=n-l,pos=0;i<n;i++)p[pos++]=i;
    		for(i=0;i<n;i++)if(sa[i]>=l)p[pos++]=sa[i]-l;
    		memset(cnt,0,sizeof cnt);
    		for(i=0;i<n;i++)cnt[rank[p[i]]]++;
    		for(i=1;i<=sig;i++)cnt[i]+=cnt[i-1];
    		for(i=n-1;i>=0;i--)sa[--cnt[rank[p[i]]]]=p[i];
    		for(temp[sa[0]]=pos=0,i=1;i<n;i++)
    		{
    			if(!equ(sa[i],sa[i-1],l))pos++;
    			temp[sa[i]]=pos;
    		}
    		for(i=0;i<n;i++)rank[i]=temp[i];
    		if(!l)l=1;else l<<=1;
    	}
    }
    void pre()
    {
    	int i,k;
    	for(i=k=0;i<n;i++)
    	{
    		if(k)k--;
    		if(rank[i]==0)continue;
    		for(int j=sa[rank[i]-1];str[i+k]==str[j+k];)
    			k++;
    		height[rank[i]]=k;
    	}
    }
    void print()
    {
    	for(int i=0;i<n;i++)
    		printf("%d ",sa[i]+1);
    	printf("
    ");
    	for(int i=1;i<n;i++)
    		printf("%d ",height[i]);
    }
    int main(){
    	init();
    	if(n==1){printf("1");return 0;}
    	doubling();
    	pre();
    	print();
    	return 0;
    }
    

      

  • 相关阅读:
    leetcode-滑动窗口
    leetcode刷题-双指针
    nlp
    机器学习
    tf-idf算法
    RNN和LSTM的理解
    DDD落地实践-战术实现心得
    DDD落地实践-战略设计心得
    测试平台系列(66) 数据驱动之基础Model
    Python小知识之对象的比较
  • 原文地址:https://www.cnblogs.com/mybing/p/8481769.html
Copyright © 2011-2022 走看看