不同子串

來源:互聯網
上載者:User

標籤:

  題目描述:給定一個有小寫英文字母構成的字串T,求其不同子串個數

  資料範圍及限制:一個串,長度不超過100000

  輸入範例1:

    ababa

  輸出範例1:

    9

  輸入範例2

    ebvylfeicorjhpovljmgqawckptcqfuynhvnqwokvowxjgvjhztxmgzwkgvuvhsilrslnzcvmconbabwrpfniknqsimyutwstzzc

  輸出範例2:

    4968

  輸入範例3:

    riokzisztaydqovqjcdnojfykqjfstevddxtxbtwgzlmwqnhijuemkxaaqmjqscdpnzgseezaexluxdmdkoijafpecganbycwsjs

  輸出範例3: 

    4999757677

  題解:

    因為每個子串都是某個尾碼的首碼,所以想到用尾碼數組,首先要知道尾碼數組中height[i]的含義,height[i]不僅指排名第i的和排名第i-1的(尾碼)的最長相同首碼,還指排名第i的和排名1~i-1的最長相同首碼,可以舉幾個例子試試。

    知道了這個性質,那麼每一個尾碼中只能由它得到的首碼的個數就是n-sa[i]-height[i],n-sa[i]得到這個尾碼的長度(我是從0開始的),height[i]個首碼在排名1~i-1的尾碼中已經得到,所以要減去,不計入答案。

 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<queue> 7 #include<vector> 8 using namespace std; 9 typedef long long LL;10 const LL maxn=200000;11 LL r[maxn],sa[maxn],wa[maxn],wb[maxn],wv[maxn],Ws[maxn];12 LL cmp(LL *r,LL a,LL b,LL l){13     return r[a]==r[b]&&r[a+l]==r[b+l];14 }15 void da(LL *r,LL *sa,LL n,LL m){16     LL i,j,p,*x=wa,*y=wb,*t;17     for(i=0;i<m;i++) Ws[i]=0;18     for(i=0;i<n;i++) Ws[x[i]=r[i]]++;19     for(i=1;i<m;i++) Ws[i]+=Ws[i-1];20     for(i=n-1;i>=0;i--) sa[--Ws[x[i]]]=i; 21     22     for(j=1,p=1;p<n;j*=2,m=p){23         for(p=0,i=n-j;i<n;i++) y[p++]=i;24         for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;25         26         for(i=0;i<n;i++) wv[i]=x[y[i]];        27         for(i=0;i<m;i++) Ws[i]=0;28         for(i=0;i<n;i++) Ws[wv[i]]++;29         for(i=0;i<m;i++) Ws[i]+=Ws[i-1];30         for(i=n-1;i>=0;i--) sa[--Ws[wv[i]]]=y[i];31         32         for(t=x,x=y,y=t,x[sa[0]]=0,p=1,i=1;i<n;i++)33             x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;34     }35 }36 LL rank[maxn],height[maxn];37 void calheight(LL *r,LL *sa,LL n){38     LL i,j,k=0;39     for(i=0;i<n;i++) rank[sa[i]]=i;40     for(i=0;i<n;height[rank[i++]]=k)41         for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);42     return ;43 }44 char s[maxn];45 LL num[maxn],len,ans;46 int main(){47     freopen("distinct.in","r",stdin);48     freopen("distinct.out","w",stdout);49     scanf("%s",s); len=strlen(s);50     for(LL i=0;i<len;i++) num[i]=s[i]-‘a‘+2;51     da(num,sa,len,30);52     calheight(num,sa,len); height[0]=0;53     for(LL i=0;i<len;i++){54         LL k=len-sa[i];55         ans+=k-height[i];56     }57     printf("%lld",ans);58     return 0;59 }

 

不同子串

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.