尾碼數組 hash求LCP BZOJ 4310: 跳蚤

來源:互聯網
上載者:User

標籤:for   答案   ges   can   clu   long   ted   ima   bzoj   

尾碼數組的題部落格裡沒放進去過。。所以挖了一題寫寫 充實下部落格 順便留作板子。。

一個字串S中 內容不同的子串 有 sigma{n-sa[i]+1-h[i]}   (噢 這裡的h[]就是大家熟知的height[])

所以l=1,r=上述sigma 二分 答案是字典序第幾大的子串。

然後 求S中第k大的子串W : 因為h[i]是與i-1有關的 所以要從n downto 1,k-=n-sa[i]+1-h[i] 至 k再減就非正了

顯然這樣掃過來 子串字典序是遞減的  因此可以得到第k大子串W

然後再貪心 n downto 1 若遇到比 W大的子串 就劃分,驗證 當前二分的這個第k大可不可行

判斷 比W大還是小 用hash 二分求LCP即可

 1 #include <bits/stdc++.h> 2 #define N 200005 3 #define LL long long 4 using namespace std; 5 const LL mo=1000000007; 6 int F[27],a[N],rank[N],sa[N],h[N],g1[N],g2[N],next[N],n,m,ans,k,t,l,r,mid,x,y,z; 7 char S[N]; LL f[N],w[N]; 8 int oh(int k,int t,int p,int q){ 9     int l=0,r=min(t-k,q-p)+1,j;10     while (l<r){11         j=l+r+1>>1;12         (f[k+j-1]-f[k-1]*w[j]%mo+mo)%mo==(f[p+j-1]-f[p-1]*w[j]%mo+mo)%mo?13         l=j:r=j-1;14     }15     if (k+l>t) return 0;16     if (p+l>q) return 1;17     return a[k+l]>a[p+l];18 }19 int jud(int u){20     int p,q,k,t;21     for (int i=n;i;--i)22         if (n-sa[i]+1-h[i]<u) u-=n-sa[i]+1-h[i];23         else {p=sa[i];q=n-u+1;break;}24     t=n; k=1;25     for (int i=n;i;)26     if (oh(i,t,p,q)){27         if (i==t) return 0;28         t=i; ++k;29     } else --i;30     if (k>m) return 0; return 1;31 }32 int main(){33     scanf("%d",&m); scanf("%s",S+1); n=strlen(S+1);34     w[0]=1;35     for (int i=1;i<=n;++i) {36         a[i]=S[i]-‘a‘+1;37         F[a[i]]=1;38         f[i]=(f[i-1]*29+a[i])%mo;39         w[i]=w[i-1]*29%mo;40     }41     for (int i=2;i<=26;++i) F[i]+=F[i-1];42     for (int i=1;i<=n;++i) rank[i]=F[a[i]]; t=F[26];43     for (int m=1;m<n;m<<=1){44         for (int i=1;i<=n;++i){45             next[i]=g1[rank[i+m]];46             g1[rank[i+m]]=i;47         }48         for (int i=t;i>=0;--i){49             for (int j=g1[i];j;j=k){50                 k=next[j]; next[j]=g2[rank[j]]; g2[rank[j]]=j;51             }52             g1[i]=0;53         }54         z=0;55         for (int i=1;i<=t;++i){56             y=-1;57             for (int j=g2[i];j;j=k){58                 k=next[j]; next[j]=0;59                 if (y!=rank[j+m]) y=rank[j+m],++z;60                 h[j]=z;61             }62             g2[i]=0;63         }64         t=z;65         for (int i=1;i<=n;++i) rank[i]=h[i];66     }67     for (int i=1;i<=n;++i) sa[rank[i]]=i,h[i]=0;68     for (int i=1;i<=n;++i)69     if (rank[i]!=1){70         k=h[rank[i-1]]; if (k) --k;71         while (a[i+k]==a[sa[rank[i]-1]+k]) ++k;72         h[rank[i]]=k; r+=n-i+1-k;73     }74     l=1; ++r;75     while (l<r){76         k=l+r+1>>1;77         jud(k)?l=k:r=k-1;78     }79     for (int i=n;i;--i)80     if (n-sa[i]+1-h[i]<l) l-=n-sa[i]+1-h[i];81     else {k=sa[i];t=n-l+1;break;}82     for (int i=k;i<=t;++i) printf("%c",a[i]+‘a‘-1);83     return 0;84 }
View Code

 

尾碼數組 hash求LCP BZOJ 4310: 跳蚤

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.