日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

SPOJ 694/705 后缀数组

發布時間:2023/12/18 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SPOJ 694/705 后缀数组 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

思路:
論文題*n
Σn-i-ht[i]+1 就是結果 O(n)搞定~

//By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 55555 int cases,n,cntA[N],cntB[N],A[N],B[N],rk[N],sa[N],tsa[N],ht[N]; char s[N]; void SA(){memset(cntA,0,sizeof(cntA));for(int i=1;i<=n;i++)cntA[s[i]]++;for(int i=1;i<=256;i++)cntA[i]+=cntA[i-1];for(int i=n;i;i--)sa[cntA[s[i]]--]=i;rk[sa[1]]=1;for(int i=2;i<=n;i++)rk[sa[i]]=rk[sa[i-1]]+(s[sa[i]]!=s[sa[i-1]]);for(int l=1;rk[sa[n]]<n;l<<=1){memset(cntA,0,sizeof(cntA));memset(cntB,0,sizeof(cntB));for(int i=1;i<=n;i++)cntA[A[i]=rk[i]]++,cntB[B[i]=i+l<=n?rk[i+l]:0]++;for(int i=1;i<=n;i++)cntA[i]+=cntA[i-1],cntB[i]+=cntB[i-1];for(int i=n;i;i--)tsa[cntB[B[i]]--]=i;for(int i=n;i;i--)sa[cntA[A[tsa[i]]]--]=tsa[i];rk[sa[1]]=1;for(int i=2;i<=n;i++)rk[sa[i]]=rk[sa[i-1]]+(A[sa[i]]!=A[sa[i-1]]||B[sa[i]]!=B[sa[i-1]]);}for(int i=1,j=0;i<=n;i++){j=j?j-1:0;while(s[i+j]==s[sa[rk[i]-1]+j])j++;ht[rk[i]]=j;} } int main(){scanf("%d",&cases);while(cases--){long long ans=0;scanf("%s",s+1),n=strlen(s+1),SA();for(int i=1;i<=n;i++)ans+=n-i-ht[i]+1;printf("%lld\n",ans);} }

轉載于:https://www.cnblogs.com/SiriusRen/p/6532077.html

總結

以上是生活随笔為你收集整理的SPOJ 694/705 后缀数组的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。