后缀数组学习&模板

后缀数组学习&模板

学习链接:

http://blog.csdn.net/whyorwhnt/article/details/32933319 ,里面说的很清楚,各个变量的解释还蛮清晰

该链接里面有很多文章,这篇有图形解释,容易理解: http://www.cppblog.com/superKiki/archive/2010/05/15/115421.html 不过有书看也更好

后缀数组的思想:

先比较所有后缀的 前2^0次方个字符,然后比较 前2^1次方个字符,然后 2^2,2^3,... 直到所有后缀的 前2^i 个字符比较不存在完全相同的情况,就停止。

1. 基数排序,用来减少排序复杂度

学习链接:http://www.cnblogs.com/Braveliu/archive/2013/01/21/2870201.html

2. 循环得出答案

3. 注意终止条件

4. 有的时候da(int *r)  ;  valheight(int *r),你可能要改为 char*r;  一般对最后一位r[n]=0赋值,最好是用任何一个小于你会用到的字符串集的字符,比如对于(A-Z)-(a-z)你就可以 r[n]='$';

5.  单纯的da是没法用的,一般我们都会用rank[]和height[],链接里也有,height保存的是LCP,即最长公共前缀。

6. RMQ,查询,查询 i位置 开始的后缀和 j位置 开始的后缀的LCP,为了减少复杂度,我们要用到简便算法,a) 线段树; b) ST算法。后者用得比较多。 

RMQ学习链接:http://kmplayer.iteye.com/blog/575725


倍增算法模板:

(注意 n 还是 n+1 ;从 1 开始 还是 从 0 开始)

const int N = int(2e5)+10;
int cmp(int *r,int a,int b,int l){
    return (r[a]==r[b]) && (r[a+l]==r[b+l]);
}
// 用于比较第一关键字与第二关键字,
// 比较特殊的地方是,预处理的时候,r[n]=0(小于前面出现过的字符)

int wa[N],wb[N],ws[N],wv[N];
int rank[N],height[N];
void DA(int *r,int *sa,int n,int m){ //此处N比输入的N要多1,为人工添加的一个字符,用于避免CMP时越界
    int i,j,p,*x=wa,*y=wb,*t;
    for(i=0;i
   
   
    
    =0;i--) sa[--ws[x[i]]]=i; //预处理长度为1
    for(j=1,p=1;p
    
    
     
     =j) y[p++]=sa[i]-j; //利用长度J的,按第二关键字排序
        for(i=0;i
     
     
      
      =0;i--) sa[--ws[wv[i]]]=y[i];  //基数排序部分
        for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i
      
      
       
       = h[i-1]-1 来优化计算height过程
}

char str[N];
int sa[N];
int main(){
    char str[N];
    scanf("%s",str);
    int n = strlen(str);
    str[n]=0;
    
    da(str,sa,n+1,128);  //注意区分此处为n+1,因为添加了一个结尾字符用于区别比较
    calheight(str,sa,n);
}

      
      
     
     
    
    
   
   

题目见

后缀数组联系专题

hdu5008-Boring String Problem(后缀数组专题)

后缀数组模板-boj477.新来的小妹妹 & boj477. 田田背课文

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值