zoukankan      html  css  js  c++  java
  • 后缀数组模板

    模板题

    学了很久,算是解决了一块心病,
    虽然大致能理解,但现在也只是停留在写模板的程度
    存个模板先

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    using namespace std;
    const int MAXN=1e6+10;
    char s[MAXN];
    int n,m,sa[MAXN],rk[MAXN],tp[MAXN],c[MAXN],height[MAXN];
    
    void getsa(){
    	m='z';
    	for(int i=1;i<=n;i++) c[rk[i]=s[i]]++;
    	for(int i=1;i<=m;i++) c[i]+=c[i-1];
    	for(int i=n;i>=1;i--) sa[c[rk[i]]--]=i;
    	for(int w=1,p=0;p<n;w<<=1,m=p){
    		p=0;
    		for(int i=n-w+1;i<=n;i++) tp[++p]=i;
    		for(int i=1;i<=n;i++) if(sa[i]>w) tp[++p]=sa[i]-w;
    		for(int i=1;i<=m;i++) c[i]=0;
    		for(int i=1;i<=n;i++) c[rk[i]]++;
    		for(int i=1;i<=m;i++) c[i]+=c[i-1];
    		for(int i=n;i>=1;i--) sa[c[rk[tp[i]]]--]=tp[i];
    		swap(rk,tp);
    		rk[sa[1]]=p=1;
    		for(int i=2;i<=n;i++)
    			rk[sa[i]]=(tp[sa[i]]==tp[sa[i-1]]&&tp[sa[i]+w]==tp[sa[i-1]+w])?p:++p;
    	}
    }
    
    void getheight(){
    	int k=0;
    	for(int i=1;i<=n;i++){
    		if(rk[i]==1) continue;
    		if(k) k--;
    		int j=sa[rk[i]-1];
    		while(i+k<=n&&j+k<=n&&s[i+k]==s[j+k]) k++;
    		height[rk[i]]=k;
    	}
    }
    
    int main(){
    	scanf("%s",s+1);
    	n=strlen(s+1);
    	getsa();
    	getheight();
    	for(int i=1;i<=n;i++) printf("%d%c",sa[i]-1,i<n?' ':'
    ');
    	for(int i=1;i<=n;i++) printf("%d%c",height[i],i<n?' ':'
    ');
    	return 0;
    }
    
  • 相关阅读:
    307.区域与检索--数组可修改
    202.快乐数
    263.丑数
    205.同构字符串
    204.计数质数
    40.组合总和Ⅱ
    811.子域名访问计数
    39.组合总和
    udp与tcp
    SQL复习
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/11980568.html
Copyright © 2011-2022 走看看