1. 程式人生 > >BZOJ5137: [Usaco2017 Dec]Standing Out from the Herd(廣義字尾自動機,Parent樹)

BZOJ5137: [Usaco2017 Dec]Standing Out from the Herd(廣義字尾自動機,Parent樹)

Description

Just like humans, cows often appreciate feeling they are unique in some way. Since Farmer John's cow s all come from the same breed and look quite similar, they want to measure uniqueness in their name s.Each cow's name has some number of substrings. For example, "amy" has substrings {a, m, y, am, my,  amy}, and "tommy" would have the following substrings: {t, o, m, y, to, om, mm, my, tom, omm, mmy,  tomm, ommy, tommy}.A cow name has a "uniqueness factor" which is the number of substrings of that na me not shared with any other cow. For example, If amy was in a herd by herself, her uniqueness facto r would be 6. If tommy was in a herd by himself, his uniqueness factor would be 14. If they were in  a herd together, however, amy's uniqueness factor would be 3 and tommy's would be 11.Given a herd of cows, please determine each cow's uniqueness factor. 定義一個字串的「獨特值」為只屬於該字串的本質不同的非空子串的個數。如 "amy" 與 “tommy” 兩個串, 只屬於 "amy" 的本質不同的子串為 "a" "am" "amy" 共 3 個。只屬於 "tommy" 的本質不同的子串為 "t" "to" " tom" "tomm" "tommy" "o" "om" "omm" "ommy" "mm" "mmy" 共 11 個。 所以 "amy" 的「獨特值」為 3 ,"tommy " 的「獨特值」為 11 。給定 N 個字符集為小寫英文字母的字串,所有字串的長度和小於 10^5 ,求出每個 字串「獨特值」

Input

The first line of input will contain NN (1≤N≤10^5).  The following NN lines will each contain the name of a cow in the herd.  Each name will contain only lowercase characters a-z.  The total length of all names will not exceed 10^5

Output

Output NN numbers, one per line, describing the uniqueness factor of each cow.

Sample Input

3
amy
tommy
bessie

Sample Output

3
11
19

解題思路:

這次略有不同,建完Parent樹之後,要在一個節點中統計子串種類。

但是並不需要想Dfs序那樣,只需要統計是否大於1就好了。

程式碼:

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 typedef long long lnt;
  5 struct sant{
  6     int tranc[26];
  7     int
len; 8 int pre; 9 }s[200000],sts; 10 struct pnt{ 11 int hd; 12 int wgt; 13 int blg; 14 }p[200000]; 15 struct ent{ 16 int twd; 17 int lst; 18 }e[200000]; 19 int fin; 20 int siz; 21 int n,T; 22 int cnt; 23 lnt ans[200000]; 24 char tmp[200000]; 25 void ade(int f,int t) 26 { 27 cnt++; 28 e[cnt].twd=t; 29 e[cnt].lst=p[f].hd; 30 p[f].hd=cnt; 31 return ; 32 } 33 void res(void) 34 { 35 fin=siz=1; 36 s[1]=s[0]=sts; 37 return ; 38 } 39 void Insert(int c,int i) 40 { 41 int nwp,lsp,nwq,lsq; 42 nwp=++siz; 43 p[nwp].blg=i; 44 p[nwp].wgt=1; 45 s[nwp].len=s[fin].len+1; 46 for(lsp=fin;lsp&&!s[lsp].tranc[c];lsp=s[lsp].pre) 47 s[lsp].tranc[c]=nwp; 48 if(!lsp) 49 s[nwp].pre=1; 50 else{ 51 lsq=s[lsp].tranc[c]; 52 if(s[lsq].len==s[lsp].len+1) 53 s[nwp].pre=lsq; 54 else{ 55 nwq=++siz; 56 s[nwq]=s[lsq]; 57 s[nwq].len=s[lsp].len+1; 58 s[nwp].pre=s[lsq].pre=nwq; 59 while(s[lsp].tranc[c]==lsq) 60 { 61 s[lsp].tranc[c]=nwq; 62 lsp=s[lsp].pre; 63 } 64 } 65 } 66 fin=nwp; 67 return ; 68 } 69 void Dfs(int x) 70 { 71 int t=p[x].blg; 72 for(int i=p[x].hd;i;i=e[i].lst) 73 { 74 int to=e[i].twd; 75 Dfs(to); 76 if(!t) 77 t=p[to].blg; 78 else if(t!=p[to].blg) 79 t=-1; 80 p[x].wgt+=p[to].wgt; 81 } 82 p[x].blg=t; 83 if(t<=0) 84 return ; 85 ans[t]+=(lnt)s[x].len-s[s[x].pre].len; 86 return ; 87 } 88 int main() 89 { 90 res(); 91 scanf("%d",&T); 92 for(int t=1;t<=T;t++) 93 { 94 fin=1; 95 lnt ans=0; 96 scanf("%s",tmp+1); 97 n=strlen(tmp+1); 98 for(int i=1;i<=n;i++) 99 Insert(tmp[i]-'a',t); 100 } 101 for(int i=2;i<=siz;i++) 102 ade(s[i].pre,i); 103 Dfs(1); 104 for(int i=1;i<=T;i++) 105 printf("%lld\n",ans[i]); 106 return 0; 107 }