码迷,mamicode.com
首页 > 编程语言 > 详细

用 二分+哈希 求后缀数组

时间:2016-04-12 01:42:05      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:

  个人感觉后缀数组的板子太难背了,听了小火车讲二分+哈希可以实现求后缀数组,貌似很好理解,代码如下。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 using namespace std;
10 typedef long long LL;
11 typedef unsigned long long ULL;
12 const int maxn=200000;
13 const ULL BASE=127;
14 char s[maxn];
15 int sa[maxn],rank[maxn];
16 ULL a[maxn],base[maxn],hash[maxn],len;
17 struct H{
18     int pos;
19 }suf[maxn];
20 inline ULL get_hash(int l,int r){
21     return hash[r]-hash[l-1]*base[r-l+1];
22 }
23 inline int find(int l,int r,int f1,int f2){
24     if(l+1>=r){
25         if(get_hash(f1,f1+r-1)==get_hash(f2,f2+r-1)) return r;
26         else return l;
27     }
28     int mid=(l+r)>>1;
29     if(get_hash(f1,f1+mid-1)==get_hash(f2,f2+mid-1)) return find(mid,r,f1,f2);
30     else return find(l,mid-1,f1,f2);
31 }
32 inline bool cmp(const H &x,const H &y){
33     int len1=len-x.pos+1,len2=len-y.pos+1;
34     int maxx=find(0,min(len1,len2)+1,x.pos,y.pos);
35     if(maxx==min(len1,len2)+1) return len1<len2;
36     else return a[x.pos+maxx]<a[y.pos+maxx];
37 }
38 int height[maxn];
39 inline void calheight(){
40     int k=0;
41     for(int i=1;i<=len;i++){
42         if(k!=0) k--;
43         for(int j=sa[rank[i]-1];;k++){
44             if(a[i+k]!=a[j+k]) break;
45         }
46         height[rank[i]]=k;
47     }
48     return ;
49 }
50 int main(){
51     scanf("%s",s+1); len=strlen(s+1);
52     for(int i=1;i<=len;i++) a[i]=ULL(s[i]-a+1);
53     base[0]=1; for(int i=1;i<=len;i++) base[i]=base[i-1]*BASE;
54     for(int i=1;i<=len;i++) hash[i]=hash[i-1]*BASE+a[i];
55     for(int i=1;i<=len;i++){
56         suf[i].pos=i;
57     }
58     sort(suf+1,suf+len+1,cmp);
59     for(int i=1;i<=len;i++){
60         sa[i]=suf[i].pos; rank[suf[i].pos]=i;
61     }
62     calheight();
63     for(int i=1;i<=len;i++){
64         cout<<height[i]<<" ";
65     }
66     return 0;
67 }

 

用 二分+哈希 求后缀数组

标签:

原文地址:http://www.cnblogs.com/CXCXCXC/p/5380755.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!