里程碑3——最小循环串

来源:互联网 发布:陕西省广电网络营业厅 编辑:程序博客网 时间:2024/05/04 13:12

树状数组是第一个让我惊叹的数据结构,后缀自动机是第二个!

#include<iostream>  #include<vector>  #include<algorithm>  #include<cstdio>  #include<queue>  #include<stack>  #include<string>  #include<map>  #include<set>  #include<cmath>  #include<cassert>  #include<cstring>  #include<iomanip>  using namespace std;  #ifdef _WIN32  #define i64 __int64  #define out64 "%I64d\n"  #define in64 "%I64d"  #else  #define i64 long long  #define out64 "%lld\n"  #define in64 "%lld"  #endif  /************ for topcoder by zz1215 *******************/  #define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)  #define FFF(i,a)        for( int i = 0 ; i < (a) ; i ++)  #define FFD(i,a,b)      for( int i = (a) ; i >= (b) ; i --)  #define S64(a)          scanf(in64,&a)  #define SS(a)           scanf("%d",&a)  #define LL(a)           ((a)<<1)  #define RR(a)           (((a)<<1)+1)  #define pb              push_back  #define CL(Q)           while(!Q.empty())Q.pop()  #define MM(name,what)   memset(name,what,sizeof(name))  #define MC(a,b)         memcpy(a,b,sizeof(b))  #define MAX(a,b)        ((a)>(b)?(a):(b))  #define MIN(a,b)        ((a)<(b)?(a):(b))  #define read            freopen("in.txt","r",stdin)  #define write           freopen("out.txt","w",stdout)    const int inf = 0x3f3f3f3f;  const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;  const double oo = 10e9;  const double eps = 10e-9;  const double pi = acos(-1.0);  const int maxz = 200111;    struct zz  {      int par;      int to[26];       int len;      void init()      {          par = 0;          len = 0;          MM(to,0);      }  }zx[maxz];    struct suffix_automaton  {      const static int head = 1;        int last;      int use;        int get()      {          zx[++use].init();          return use;      }        void init()      {             last=1;          use=0;          get();          return ;      }            void extend(int c)      {             int end = get();          int now = last;        zx[end].len = zx[last].len+1;          last = end;        for (; now && !zx[now].to[c]; now=zx[now].par)          {              zx[now].to[c]=end;          }          if (!now)          {                 zx[end].par = head;          }          else          {              int to = zx[now].to[c];              if (zx[now].len+1 == zx[to].len)              {                  zx[end].par = to;              }              else              {                  int np = get();                  zx[np] = zx[to];                      zx[np].len = zx[now].len +1;                  zx[end].par = zx[to].par = np;                  for (; now && zx[now].to[c] == to; now=zx[now].par)                   {                      zx[now].to[c]=np;                  }              }          }      }  }SA;      int main()  {      string s;      string ans;      while(cin>>s)      {          SA.init();          int c;          for(int i=0;i<s.length();i++)          {              c = s[i]-'a';                         SA.extend(c);                     }          for(int i=0;i<s.length();i++)          {              c = s[i]-'a';              SA.extend(c);          }          ans = "";          int now = SA.head;                    char ch;          for(int i=0;i<s.length();i++)          {              for(int j=0;j<26;j++)              {                             if(zx[now].to[j])                  {                      now = zx[now].to[j];                      ch = 'a' + j;                      ans+=ch;                      break;                  }              }          }          cout<<ans<<endl;      }      return 0;  }  


原创粉丝点击