zoukankan      html  css  js  c++  java
  • 用 二分+哈希 求后缀数组

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

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<queue>
     8 #include<vector>
     9 #include<ctime>
    10 using namespace std;
    11 typedef unsigned long long ULL;
    12 const ULL BASE=127;
    13 const int maxn=6000000;
    14 ULL base[maxn],hash[maxn];
    15 int len;
    16 char s[maxn];
    17 inline ULL get_hash(int l,int r){
    18     return hash[r]-hash[l-1]*base[r-l+1];
    19 }
    20 struct S{
    21     int pos;
    22 }suf[maxn];
    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 S & x,const S & 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 x.pos>y.pos;
    36     else return s[x.pos+maxx]<s[y.pos+maxx];
    37 }
    38 int sa[maxn],rank[maxn],height[maxn];
    39 int main(){
    40     freopen("makedata.out","r",stdin);
    41     freopen("mine.out","w",stdout);
    42     scanf("%s",s+1); len=strlen(s+1);
    43     base[0]=1; for(int i=1;i<=len;i++) base[i]=base[i-1]*BASE;
    44     for(int i=1;i<=len;i++) hash[i]=hash[i-1]*BASE+s[i]-'a'+1;
    45     for(int i=1;i<=len;i++) suf[i].pos=i;
    46     sort(suf+1,suf+len+1,cmp);
    47     for(int i=1;i<=len;i++){
    48         rank[suf[i].pos]=i;
    49         sa[i]=suf[i].pos;
    50     }
    51     for(int i=2;i<=len;i++){
    52         int len1=len-sa[i-1]+1,len2=len-sa[i]+1;
    53         height[i]=find(0,min(len1,len2),sa[i-1],sa[i]);
    54     }
    55     for(int i=1;i<=len;i++){
    56         printf("%d %d
    ",sa[i],height[i]);
    57     }
    58     return 0;
    59 }
  • 相关阅读:
    socket-重叠模型(overlap)
    ssh 免密登陆
    安装google 框架
    为什么不同网段的ip 不能直接通信
    python中的import,reload,以及__import__
    C Runtime Library、C  Runtime
    SQLite3 C/C++ 开发接口简介
    mysql添加索引语句
    mysql 字段左右补0
    @Transactional注解的失效场景
  • 原文地址:https://www.cnblogs.com/CXCXCXC/p/5380755.html
Copyright © 2011-2022 走看看