Match & Catch CodeForces - 427D suffix automaton water problem

Meaning of the questions:

Given two strings a, b, seeking a string that is a substring of a and b,

Occurs only once and a, b, the minimum required length of the output string.

answer:

The suffix automaton into a string, and then click the recording frequency corresponding to each node appears substring

Then the string from the matching incentive b

Then judge for themselves

 

  1 #include <set>
  2 #include <map>
  3 #include <stack>
  4 #include <queue>
  5 #include <cmath>
  6 #include <ctime>
  7 #include <cstdio>
  8 #include <string>
  9 #include <vector>
 10 #include <cstring>
 11 #include <iostream>
 12 #include <algorithm>
 13 #include <unordered_map>
 14 
 15 #define  pi    acos(-1.0)
 16 #define  eps   1e-9
 17 #define  fi    first
 18 #define  se    second
 19 #define  rtl   rt<<1
 20 #define  rtr   rt<<1|1
 21 #define  bug                printf("******\n")
 22 #define  mem(a, b)          memset(a,b,sizeof(a))
 23 #define  name2str(x)        #x
 24 #define  fuck(x)            cout<<#x" = "<<x<<endl
 25 #define  sfi(a)             scanf("%d", &a)
 26 #define  sffi(a, b)         scanf("%d %d", &a, &b)
 27 #define  sfffi(a, b, c)     scanf("%d %d %d", &a, &b, &c)
 28 #define  sffffi(a, b, c, d) scanf("%d %d %d %d", &a, &b, &c, &d)
 29 #define  sfL(a)             scanf("%lld", &a)
 30 #define  sffL(a, b)         scanf("%lld %lld", &a, &b)
 31 #define  sfffL(a, b, c)     scanf("%lld %lld %lld", &a, &b, &c)
 32 #define  sffffL(a, b, c, d) scanf("%lld %lld %lld %lld", &a, &b, &c, &d)
 33 #define  sfs(a)             scanf("%s", a)
 34 #define  sffs(a, b)         scanf("%s %s", a, b)
 35 #define  sfffs(a, b, c)     scanf("%s %s %s", a, b, c)
 36 #define  sffffs(a, b, c, d) scanf("%s %s %s %s", a, b,c, d)
 37 #define  FIN                freopen("../in.txt","r",stdin)
 38 #define  gcd(a, b)          __gcd(a,b)
 39 #define  lowbit(x)          x&-x
 40 #define  IO                 iOS::sync_with_stdio(false)
 41 
 42 
 43 using namespace std;
 44 typedef long long LL;
 45 typedef unsigned long long ULL;
 46 const ULL seed = 13331;
 47 const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
 48 const int maxm = 8e6 + 10;
 49 const int INF = 0x3f3f3f3f;
 50 const int mod = 1e9 + 7;
 51 const int maxn = 250007;
 52 char s[maxn];
 53 int Q;
 54 
 55 struct Suffix_Automaton {
 56     int last, tot, nxt[maxn << 1][26], fail[maxn << 1 ]; // number belongs longest prefix node is not added last before this character (the entire string) 
57 is      int len [MAXN << 1 ]; // longest substring length (the number of nodes = len substring len [FA [X]]) - [X] 
58      int SA [MAXN << . 1 ], C [MAXN << . 1 ;]
 59      int SZ [MAXN << . 1 ;] // number suffixes are linked, to facilitate the number of nodes required string 
60      LL NUM [MAXN << . 1 ]; // this state, the number of sub-string 
61 is      LL Maxx [MAXN << . 1 ]; // length sub-string x largest number of occurrences of substrings The number 
62 is      LL SUM [MAXN << . 1 ]; //Since the string is formed behind the total number of the node 
63 is      LL subnum, sublen; // subnum represents a different number of strings, sublen different string length represents the total 
64      int X-[MAXN << . 1 ], the Y [MAXN << . 1 ] ; // the Y represents ranked node x, x represents how many there are in front of the length 
65      int Minn [MAXN << . 1 ], MX [MAXN << . 1 ]; // Minn [I] represents a plurality of strings suffix automaton node i longest common substring, mx [i] represents a single string of the longest common substring 
66      void the init () {
 67          TOT = Last = . 1 ;
 68          Fail [ . 1 ] = len [ . 1 ] = 0 ;
 69          for (int i = 0; i < 26; i++) nxt[1][i] = 0;
 70     }
 71 
 72     void extend(int c) {
 73         int u = ++tot, v = last;
 74         len[u] = len[v] + 1;
 75         num[u] = 1;
 76         for (; v && !nxt[v][c]; v = fail[v]) nxt[v][c] = u;
 77         if (!v) fail[u] = 1, sz[1]++;
 78         else if (len[nxt[v][c]] == len[v] + 1) fail[u] = nxt[v][c], sz[nxt[v][c]]++;
 79         else {
 80             int now = ++tot, cur = nxt[v][c];
 81             len[now] = len[v] + 1;
 82             memcpy(nxt[now], nxt[cur], sizeof(nxt[cur]));
 83             fail[now] = fail[cur];
 84             fail[cur] = fail[u] = now;
 85             for (; v && nxt[v][c] == cur; v = fail[v]) nxt[v][c] = now;
 86             sz[now] += 2;
 87         }
 88          Last = U;
 89          // return len [Last] - len [Fail [Last]]; // add more a number of different sub-sub-string generated strings 
90      }
 91 is  
92      void get_num () { // each node substring occurring number 
93          for ( int I = . 1 ; I <= TOT; I ++) X-[len [I]] ++ ;
 94          for ( int I = . 1 ; I <= TOT; I ++) X-[I ] X-+ = [I - . 1 ];
 95          for ( int I = . 1 ; I <= TOT; I ++) the Y [X-[len [I]] -] = I;
 96         for ( int I = TOT; I> = . 1 ; i--) NUM [Fail [the Y [I]]] + = NUM [the Y [I]];
 97      }
 98  
99      void get_maxx ( int n-) { // length the number of sub x string occurs most often substrings 
100          get_num ();
 101          for ( int I = . 1 ; I <= TOT; I ++) Maxx [len [I]] = max (Maxx [len [I]] , NUM [I]);
 102      }
 103  
104      void get_sum () { // total number string formed from the rear node 
105          get_num ();
 106          for ( intTOT = I; I> = . 1 ; i-- ) {
 107              SUM [the Y [I]] = . 1 ;
 108              for ( int J = 0 ; J <= 25 ; J ++ )
 109                  SUM [the Y [I]] = + SUM [NXT [the Y [I]] [J]];
 110          }
 111      }
 112  
113      void get_subnum () { // essentially different from the number of sub-strings 
114          subnum = 0 ;
 115          for ( int I = . 1 ; I < TOT =; I ++) subnum + = len [I] - len [Fail [I]];
1 16      }
 117  
1 18      void get_sublen () { // essentially different from the substring of the total length of 
119          sublen = 0 ;
 120          for ( int I = . 1 ; I <= TOT; I ++) sublen + = 1LL * (len [I] + len [Fail [I]] + . 1 ) * (len [I] - len [Fail [I]]) / 2 ;
 121      }
 122  
123      void get_sa () { // Get sa array 
124          for ( int I = . 1 ; I <= TOT; I ++) C [len [I]] ++ ;
 125          for ( int I =. 1 ; I <= TOT; I ++) C [I] + C = [I - . 1 ];
 126          for ( int I = TOT; I> = . 1 ; i--) SA [C [len [I]] - ] = I;
 127      }
 128  
129      int cntnum [MAXN << . 1 ];
 130.  
131 is      void match () { // plurality of longest common substring of string 
132          MEM (cntnum, 0 );
 133          int n-= strlen (S ), P = . 1 , ANS = INF;
 134          for ( int I = 0 ; I <n-; I ++ ) {
 135             int c = s[i] - 'a';
136             if (nxt[p][c]) p = nxt[p][c];
137             else {
138                 for (; p && !nxt[p][c]; p = fail[p]);
139                 if (!p) p = 1;
140                 else p = nxt[p][c];
141             }
142             cntnum[p]++;
143         }
144         for (int i = tot; i; i--) cntnum[fail[Y[i]]] += cntnum[Y[i]];
145         for (int i = 2 ; I <= TOT; I ++ )
 146              IF (NUM [I] == . 1 && cntnum [I] == . 1 ) ANS = min (ANS, len [Fail [I]] + . 1 );
 147          IF (ANS = INF =) the printf ( " -1 \ n- " );
 148          the else the printf ( " % D \ n- " , ANS);
 149      }
 150  
151      void get_kth ( int K) { // determine the K sub-sequence string dictionary 
152          int POS = . 1 , CNT;
 153          String S = "" ;
 154         while (k) {
155             for (int i = 0; i <= 25; i++) {
156                 if (nxt[pos][i] && k) {
157                     cnt = nxt[pos][i];
158                     if (sum[cnt] < k) k -= sum[cnt];
159                     else {
160                         k--;
161                         pos = cnt;
162                         s += (char) (i + 'a');
163                         break;
164                     }
165                 }
166             }
167         }
168         cout << s << endl;
169     }
170 
171 } sam;
172 
173 int main() {
174 #ifndef ONLINE_JUDGE
175     FIN;
176 #endif
177     sam.init();
178     sfs(s + 1);
179     int n = strlen(s + 1);
180     for (int i = 1; i <= n; i++) sam.extend((s[i] - 'a'));
181     sfs(s);
182     sam.get_num();
183     sam.match();
184 #ifndef ONLINE_JUDGE
185     cout << "Totle Time : " << (double) clock() / CLOCKS_PER_SEC << "s" << endl;
186 #endif
187     return 0;
188 }
View Code

 

Guess you like

Origin www.cnblogs.com/qldabiaoge/p/11566941.html