Bzoj topic 3172: [Tjoi2013] Word (ac automaton | | AC Automaton +fail Tree | | Suffix Array Violence | | Suffix array +rmq+ Two-way five posture water over)

Source: Internet
Author: User

3172: [Tjoi2013] Word time limit: ten Sec Memory Limit: MB
Submit: 1890 Solved: 877
[Submit] [Status] [Discuss] Description

Someone reads a paper, a paper is made up of many words. But he found that a word would appear many times in the paper, and now wondered how many times each word appeared in the paper.

Input

The first integer n, which represents how many words, and the next n rows of one word per line. Each word is made up of lowercase letters, n<=200, and the word length does not exceed 10^6

Output

outputs n integers, and the number in line I indicates how many times the first word appears in the article.

Sample Input3
A
Aa
AAASample Output6
3
1HINT

Source

A look at the problem, feel super water, directly with the AC automaton blind, and then ran more than 9,000 MS, nearly timed out, scared to cry, and then Baidu people are using the suffix array +rmq or AC automata +fail tree write, fail tree do not understand what ghost,, with a suffix array of water a bit, All the strings connected to a string, the middle separated, and then find each occurrence of the number of lines, by the nature of the suffix array can be known, is to find height greater than the length of the maximum backward maximum distance is, this would like to use RMQ and two points to try, feel a little trouble, with the violence of the trial, sample to, Submitted, ran more than 1000 MS is very good, when the feeling of violence is not too slow, using rmq+ two points to try, ran more than 2000 ms than violence to slow, but still feel may be weak data problems, the second should be a better way of writing, and then went to learn the fail tree, Actually very simple is to put the fail pointer back into the tree, has been added to the Root,ac Automatic array version of the reverse plus the value of fail reference a bit of hzw, worship Middle School students AH ~ ~ ~ ~ ~ ~ ~, ran more than 300 ms, indeed bunker,, but has not been accustomed to the array version of the kind of writing, Have an honest write over the structure of the, built the fail tree, feel good understanding more, ran more than 400 MS, also not slow ~ ~

AC Code

Nude AC automatic machine engage

/************************************************************** problem:3172 user:kxh1995 language:c++ Resu lt:accepted time:9228 Ms memory:314756 kb****************************************************************/#include  <stdio.h> #include <string.h> #include <queue> #include <iostream> using namespace std;  const int Maxnode=1000000+10;const int sg_size=27;      Char str[200000010],key[1000010];int pos[220];struct Trie {int ch[maxnode][sg_size];         int Val[maxnode];       int F[maxnode];    int Num[maxnode];      int sz;        void Init () {sz=1;        memset (ch,0,sizeof (ch));        Memset (Val,0,sizeof (Val));        memset (F,0,sizeof (f));    memset (num,0,sizeof (num));      } int idx (char c) {return C ' a ';          } int Insert (char *s) {int u=0,i;              for (i=0;s[i];i++) {int c=idx (s[i]);      if (!ch[u][c]) ch[u][c]=sz++;;      U=CH[U][C];          } val[u]++;          num[u]=0;      return u;          } void Build_ac () {queue<int>q;          int i;          for (i=0;i<sg_size;i++) {if (Ch[0][i]) Q.push (Ch[0][i]);          } int r,c,u,v;              while (!q.empty ()) {R=q.front ();              Q.pop ();                  for (c=0;c<sg_size;c++) {u=ch[r][c];                  if (!u) continue;                  Q.push (U);                  V=F[R];                      while (v&&ch[v][c]==0) v=f[v];              F[U]=CH[V][C];          }}} void Find (char *s) {int j=0;              for (int i=0;s[i];i++) {int c=idx (s[i]);              while (j&&ch[j][c]==0) j=f[j];              J=CH[J][C];              int temp=j;            while (temp)  {num[temp]++;              TEMP=F[TEMP];  }}}}ac;    int main () {int n;        while (scanf ("%d", &n)!=eof) {int i;        Ac.init ();        int Len;            for (i=1;i<=n;i++) {scanf ("%s", key);            Pos[i]=ac.insert (key);            strcat (Str,key);            Len=strlen (str);            Str[len]= ' z ' +1;        str[len+1]= ' + ';        } ac.build_ac ();        Ac.find (str);        for (i=1;i<=n;i++) {printf ("%d\n", Ac.num[pos[i]]); }    }}

Suffix array violence version

/************************************************************** problem:3172 user:kxh1995 language:c++ Resu lt:accepted time:1528 ms memory:25712 kb****************************************************************/#include & lt;stdio.h> #include <string.h> #include <algorithm> #include <iostr eam> #define MIN (A, b) (A&GT;B?B:A) #define MAX (A, B) (A&GT;B?A:B) #define N 1001000 u            Sing namespace std;          Char Str[n];   int sa[n],rank[n],rank2[n],height[n],c[n],*x,*y,s[n],k;            void cmp (int n,int sz) {int i;            Memset (C,0,sizeof (c));            for (i=0;i<n;i++) c[x[y[i]]]++;            for (i=1;i<sz;i++) c[i]+=c[i-1];        for (i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];            } void Build_sa (char *s,int n,int sz) {x=rank,y=rank2;            int i,j; for (i=0;i<n;i++) x[i]=s[i],y[i]=i;            CMP (N,SZ);            int Len;                for (len=1;len<n;len<<=1) {int yid=0;                for (i=n-len;i<n;i++) {y[yid++]=i;                    } for (i=0;i<n;i++) if (Sa[i]>=len) Y[yid++]=sa[i]-len;                CMP (N,SZ);                Swap (x, y);                X[sa[0]]=yid=0; for (i=1;i<n;i++) {if (y[sa[i-1]]==y[sa[i]]&&sa[i-1]+len<n&&sa[i]+l                    En<n&&y[sa[i-1]+len]==y[sa[i]+len]) X[sa[i]]=yid;                else X[sa[i]]=++yid;                } sz=yid+1;            if (sz>=n) break;        } for (i=0;i<n;i++) rank[i]=x[i]; } void GetHeight (char *s,int N) {inT k=0;                for (int i=0;i<n;i++) {if (rank[i]==0) continue;                K=max (0,k-1);                int j=sa[rank[i]-1];                while (S[i+k]==s[j+k]) k++;            Height[rank[i]]=k;    }} int L[220],r[220];int main () {int KK;        while (scanf ("%d", &kk)!=eof) {int n=0;        int i,j;            for (i=1;i<=kk;i++) {scanf ("%s", str+n);            L[i]=n;            N=strlen (str);            R[i]=n-l[i];        Str[n++]= ' z ' +1;        } str[n]=0;        Build_sa (str,n+1,128);        GetHeight (Str,n);            for (i=1;i<=kk;i++) {int t=rank[l[i]],len=r[i],rr,ll;                for (j=t;j&&height[j]>=len;j--);            Ll=j;                for (j=t+1;j<n&&height[j]>=len;j++);            Rr=j;        printf ("%d\n", rr-ll); }    }}

Suffix array +rmq+ two-part version

/************************************************************** problem:3172 user:kxh1995 language:c++ Resu lt:accepted time:2756 Ms memory:107824 kb****************************************************************/#include <stdio.h> #include <string.h> #include <algorithm> #include <iost         ream> #define MIN (A, b) (A&GT;B?B:A) #define MAX (A, B) (A&GT;B?A:B) #define N 1001000            using namespace Std;          Char Str[n];   int sa[n],rank[n],rank2[n],height[n],c[n],*x,*y,s[n],k;            void cmp (int n,int sz) {int i;            Memset (C,0,sizeof (c));            for (i=0;i<n;i++) c[x[y[i]]]++;            for (i=1;i<sz;i++) c[i]+=c[i-1];        for (i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];            } void Build_sa (char *s,int n,int sz) {x=rank,y=rank2;            int i,j; Fori=0;i<n;i++) x[i]=s[i],y[i]=i;            CMP (N,SZ);            int Len;                for (len=1;len<n;len<<=1) {int yid=0;                for (i=n-len;i<n;i++) {y[yid++]=i;                    } for (i=0;i<n;i++) if (Sa[i]>=len) Y[yid++]=sa[i]-len;                CMP (N,SZ);                Swap (x, y);                X[sa[0]]=yid=0; for (i=1;i<n;i++) {if (y[sa[i-1]]==y[sa[i]]&&sa[i-1]+len<n&&sa[i]+l                    En<n&&y[sa[i-1]+len]==y[sa[i]+len]) X[sa[i]]=yid;                else X[sa[i]]=++yid;                } sz=yid+1;            if (sz>=n) break;        } for (i=0;i<n;i++) rank[i]=x[i]; } void GetHeight (char *s,int n) {iNT K=0;                for (int i=0;i<n;i++) {if (rank[i]==0) continue;                K=max (0,k-1);                int j=sa[rank[i]-1];                while (S[i+k]==s[j+k]) k++;            Height[rank[i]]=k;      }} int minv[n][20],lg[n];        void Init_lg () {int i;        lg[1]=0;        for (i=2;i<n;i++) {lg[i]=lg[i>>1]+1;        }} void Init_rmq (int n) {int i,j,k;        for (i=1;i<=n;i++) {minv[i][0]=height[i];                  } for (j=1;j<=lg[n];j++) {for (k=0;k+ (1<<j) -1<=n;k++) {               Minv[k][j]=min (minv[k][j-1],minv[k+ (1<< (j-1))][j-1]);        }}} int LCP (int l,int R) {if (l>r) swap (L,R);        l++;        int k=lg[r-l+1];      return min (minv[l][k],minv[r-(1<<k) +1][k]); } int L[220],r[220];intMain () {int KK;        while (scanf ("%d", &kk)!=eof) {int n=0;        int i,j;            for (i=1;i<=kk;i++) {scanf ("%s", str+n);            L[i]=n;            N=strlen (str);            R[i]=n-l[i];        Str[n++]= ' z ' +1;        } str[n]=0;        Build_sa (str,n+1,128);        GetHeight (Str,n);        INIT_LG ();        INIT_RMQ (n);            for (i=1;i<=kk;i++) {int t=rank[l[i]],len=r[i],rr,ll;            int ml=0,mr=t;            int ans=0,tot=1;                while (ML&LT;=MR) {int mid= (ML+MR) >>1;                    if (LCP (mid,t) >=len) {ans=mid;                Mr=mid-1;            } else ml=mid+1;            }//ll=ans;            printf ("*******%d\n", LL);            if (ans) ans=t-ans+1;            Tot+=ans;            ml=t+1,mr=n-1;            ans=0;     while (ML&LT;=MR)       {int mid= (ML+MR) >>1;                    if (LCP (T+1,mid) >=len) {ans=mid;                ml=mid+1;            } else mr=mid-1;            } if (ans) ans=ans-t;        Tot+=ans;        Rr=ans;            printf ("********%d\n", RR);        printf ("%d\n", tot); }    }}

AC automaton inverse plus fail value array version

/************************************************************** problem:3172 user:kxh1995 language:c++ Resu lt:accepted time:324 ms memory:115532 kb****************************************************************/#include &  lt;stdio.h> #include <string.h> #include <queue> #include <iostream> using namespace std;  const int Maxnode=1000000+10;const int sg_size=26;          Char key[1000010];int pos[220];struct Trie {int ch[maxnode][sg_size];       int F[maxnode];    int Sum[maxnode];    int Q[maxnode];      int sz;    void Init () {sz=1;        memset (ch,0,sizeof (ch));        for (int i=0;i<26;i++) ch[0][i]=1;        memset (F,0,sizeof (f));    memset (sum,0,sizeof (sum));      } int idx (char c) {return C ' a ';          } int Insert (char *s) {int u=1,i;              for (i=0;s[i];i++) {int c=idx (s[i]);     if (!ch[u][c]) Ch[u][c]=++sz;       U=CH[U][C];        sum[u]++;      } return u;        } void Build_ac () {int head=0;        int tail=1;        Q[0]=1;              while (head!=tail) {int r=q[head];              head++;                  for (int c=0;c<sg_size;c++) {int u=ch[r][c];                  if (!u) continue;                  Q[tail++]=u;                  int V=f[r];                      while (v&&ch[v][c]==0) v=f[v];              F[U]=CH[V][C];        }} for (int i=tail-1;i>=0;i--) {sum[f[q[i]]]+=sum[q[i]];  }}}ac;    int main () {int n;        while (scanf ("%d", &n)!=eof) {int i;        Ac.init ();        int Len;            for (i=1;i<=n;i++) {scanf ("%s", key);        Pos[i]=ac.insert (key);        } ac.build_ac (); for (i=1;i<=n;i++) {printf ("%d\n", AC. Sum[pos[i]]); }    }}

AC Automaton +fail Tree

/************************************************************** problem:3172 user:kxh1995 language:c++ Resu lt:accepted time:452 ms memory:229136 kb****************************************************************/#include &  lt;stdio.h> #include <string> #include <string.h> #include <iostream> using namespace std;  Char key[1000001];  int head,tail;      int sz=0;struct Node {node *fail;      Node *next[26];      int cnt,num;          Node () {fail=null;          cnt=0;          for (int i=0;i<26;i++) next[i]=null;    num=sz++;    }}*q[26000500],*p1[220];struct edge{node *y; Edge *next;}  *b[26000100];node *root;    void Add (node *x,node *y) {Edge *k=new edge;    k->y=y;    k->next=b[x->num]; B[x->num]=k;}      void Insert (char *s,int key) {int temp,len,i;      Node *p=root;      Len=strlen (s);          for (i=0;i<len;i++) {temp=s[i]-' a ';  if (p->next[temp]==null)            P->next[temp]=new node ();         p=p->next[temp];     p->cnt++;  } p1[key]=p;}    void Build_ac () {head=tail=0;      Q[tail++]=root;          while (Head!=tail) {node *p=q[head++];          Node *temp=null;                  for (int i=0;i<26;i++) {if (p->next[i]!=null) {if (p==root)                    {p->next[i]->fail=root;                Add (Root,p->next[i]);                      } else {temp=p->fail;                              while (Temp!=null) {if (temp->next[i]!=null) {                            p->next[i]->fail=temp->next[i];                            Add (Temp->next[i],p->next[i]);                          Break                      } temp=temp->fail;               }       if (temp==null) {p->next[i]->fail=root;                    Add (Root,p->next[i]);              }} q[tail++]=p->next[i];    }}}} void Dfs (node *fa) {Edge *p;        For (P=b[fa->num];p!=null;p=p->next) {dfs (p->y);    fa->cnt+=p->y->cnt;      }}int Main () {int n;          while (scanf ("%d", &n)!=eof) {head=tail=0;        sz=0;        Root=new node ();        int i;              for (i=1;i<=n;i++) {scanf ("%s", key);          Insert (key,i);          } build_ac ();        DFS (root);        for (i=1;i<=n;i++) {printf ("%d\n", p1[i]->cnt);   }    }  }


Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Bzoj topic 3172: [Tjoi2013] Word (ac automaton | | AC Automaton +fail Tree | | Suffix Array Violence | | Suffix array +rmq+ Two-way five posture water over)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.