Advertisement
cosenza987

Untitled

Jun 21st, 2023
826
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.39 KB | None | 0 0
  1. //Слава Україні, Героям слава
  2.  
  3. #include <bits/stdc++.h>
  4.  
  5. using namespace std;
  6.  
  7. template <int ALPHA_SIZE = 62>
  8. struct Aho {
  9.     struct Node {
  10.         int p, char_p, link = -1, str_idx = -1, nxt[ALPHA_SIZE];
  11.         bool has_end = false;
  12.         Node(int _p = -1, int _char_p = -1) : p(_p), char_p(_char_p) {
  13.             fill(nxt, nxt + ALPHA_SIZE, -1);
  14.         }
  15.     };
  16.  
  17.     vector<Node> nodes = { Node() };
  18.     int ans, cnt = 0;
  19.     bool build_done = false;
  20.     vector<pair<int, int>> rep;
  21.     vector<int> ord, occur;
  22.  
  23.     // change this if different alphabet
  24.     int remap(char c) {
  25.         if (islower(c)) return c - 'a';
  26.         if (isalpha(c)) return c - 'A' + 26;
  27.         return c - '0' + 52;
  28.     }
  29.  
  30.     void add(string& p, int id = -1) {
  31.         int u = 0;
  32.         if (id == -1) id = cnt++;
  33.  
  34.         for (char ch : p) {
  35.             int c = remap(ch);
  36.             if (nodes[u].nxt[c] == -1) {
  37.                 nodes[u].nxt[c] = (int)nodes.size();
  38.                 nodes.push_back(Node(u, c));
  39.             }
  40.  
  41.             u = nodes[u].nxt[c];
  42.         }
  43.  
  44.         nodes[u].str_idx = id;
  45.         nodes[u].has_end = true;
  46.     }
  47.  
  48.     void build() {
  49.         build_done = true;
  50.         queue<int> q;
  51.  
  52.         for (int i = 0; i < ALPHA_SIZE; i++) {
  53.             if (nodes[0].nxt[i] != -1) q.push(nodes[0].nxt[i]);
  54.             else nodes[0].nxt[i] = 0;
  55.         }
  56.  
  57.         while (q.size()) {
  58.             int u = q.front();
  59.             ord.push_back(u);
  60.             q.pop();
  61.  
  62.             int j = nodes[nodes[u].p].link;
  63.             if (j == -1) nodes[u].link = 0;
  64.             else nodes[u].link = nodes[j].nxt[nodes[u].char_p];
  65.  
  66.             nodes[u].has_end |= nodes[nodes[u].link].has_end;
  67.  
  68.             for (int i = 0; i < ALPHA_SIZE; i++) {
  69.                 if (nodes[u].nxt[i] != -1) q.push(nodes[u].nxt[i]);
  70.                 else nodes[u].nxt[i] = nodes[nodes[u].link].nxt[i];
  71.             }
  72.         }
  73.         occur = vector<int>(cnt);
  74.     }
  75.  
  76.     int match(string& s, int k) {
  77.         if (!cnt) return 0;
  78.         if (!build_done) build();
  79.  
  80.         ans = 0;
  81.         //fill(occur.begin(), occur.end(), 0);
  82.         //fill(occur_aux.begin(), occur_aux.end(), 0);
  83.         int u = 0;
  84.         for (char ch : s) {
  85.             int c = remap(ch);
  86.             u = nodes[u].nxt[c];
  87.             for(int cur = u; cur != 0; cur = nodes[cur].link) {
  88.                 if(nodes[cur].str_idx != -1) occur[nodes[cur].str_idx] = k;
  89.             }
  90.         }
  91.  
  92.         /*sort(nord.rbegin(), nord.rend(), [&](int a, int b) {
  93.             return rord[a] < rord[b];
  94.         });
  95.  
  96.         for(auto &v : nord) {
  97.             int fv = nodes[v].link;
  98.             occur_aux[fv] = k;
  99.  
  100.             if(nodes[v].str_idx != -1) {
  101.                 occur[nodes[v].str_idx] = k;
  102.             }
  103.         } */
  104.  
  105.         /*for (int i = (int)ord.size() - 1; i >= 0; i--) {
  106.             int v = ord[i];
  107.             int fv = nodes[v].link;
  108.             occur_aux[fv] += occur_aux[v];
  109.             if (nodes[v].str_idx != -1) {
  110.                 occur[nodes[v].str_idx] = occur_aux[v];
  111.                 ans += occur_aux[v];
  112.             }
  113.         }*/
  114.  
  115.         //for (pair<int, int> x : rep) occur[x.first] = occur[x.second];
  116.         return ans;
  117.     }
  118. };
  119.  
  120. const int N = 1e4 + 7;
  121.  
  122. string v[N];
  123. int dp[N];
  124.  
  125. int main() {
  126.     ios_base::sync_with_stdio(false);
  127.     cin.tie(nullptr);
  128.     //freopen("in.txt", "r", stdin);
  129.     //freopen("output.txt", "w", stdout);
  130.     //auto start = chrono::high_resolution_clock::now();
  131.     int n;
  132.     while(cin >> n) {
  133.         if(!n) break;
  134.         Aho<26> aho;
  135.         for(int i = 0; i < n; i++) {
  136.             dp[i] = 1;
  137.             cin >> v[i];
  138.         }
  139.         sort(v, v + n, [](string &a, string &b) {
  140.             return a.size() < b.size();
  141.         });
  142.         for(int i = 0; i < n; i++) {
  143.             aho.add(v[i]);
  144.         }
  145.         aho.build();
  146.         int ans = 0;
  147.         for(int i = 0; i < n; i++) {
  148.             aho.match(v[i], i + 1);
  149.             for(int j = 0; j < i; j++) {
  150.                 if(aho.occur[j] == i + 1) {
  151.                     dp[i] = max(dp[i], dp[j] + 1);
  152.                 }
  153.             }
  154.             ans = max(ans, dp[i]);
  155.         }
  156.         cout << ans << "\n";
  157.     }
  158.     //auto stop = chrono::high_resolution_clock::now();
  159.     //cerr << chrono::duration_cast<chrono::milliseconds>(stop - start).count() << "\n";
  160.     return 0;
  161. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement