Advertisement
cosenza987

Untitled

Jun 21st, 2023
795
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.80 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, occur_aux;
  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.         if (nodes[u].str_idx != -1) rep.push_back({ id, nodes[u].str_idx });
  45.         else nodes[u].str_idx = id;
  46.         nodes[u].has_end = true;
  47.     }
  48.  
  49.     void build() {
  50.         build_done = true;
  51.         queue<int> q;
  52.  
  53.         for (int i = 0; i < ALPHA_SIZE; i++) {
  54.             if (nodes[0].nxt[i] != -1) q.push(nodes[0].nxt[i]);
  55.             else nodes[0].nxt[i] = 0;
  56.         }
  57.  
  58.         while (q.size()) {
  59.             int u = q.front();
  60.             ord.push_back(u);
  61.             q.pop();
  62.  
  63.             int j = nodes[nodes[u].p].link;
  64.             if (j == -1) nodes[u].link = 0;
  65.             else nodes[u].link = nodes[j].nxt[nodes[u].char_p];
  66.  
  67.             nodes[u].has_end |= nodes[nodes[u].link].has_end;
  68.  
  69.             for (int i = 0; i < ALPHA_SIZE; i++) {
  70.                 if (nodes[u].nxt[i] != -1) q.push(nodes[u].nxt[i]);
  71.                 else nodes[u].nxt[i] = nodes[nodes[u].link].nxt[i];
  72.             }
  73.         }
  74.         occur = vector<int>(cnt);
  75.         occur_aux = vector<int>(nodes.size());
  76.     }
  77.  
  78.     int match(string& s) {
  79.         if (!cnt) return 0;
  80.         if (!build_done) build();
  81.  
  82.         ans = 0;
  83.         fill(occur.begin(), occur.end(), 0);
  84.         fill(occur_aux.begin(), occur_aux.end(), 0);
  85.  
  86.         int u = 0;
  87.         for (char ch : s) {
  88.             int c = remap(ch);
  89.             u = nodes[u].nxt[c];
  90.             occur_aux[u]++;
  91.         }
  92.  
  93.         for (int i = (int)ord.size() - 1; i >= 0; i--) {
  94.             int v = ord[i];
  95.             int fv = nodes[v].link;
  96.             occur_aux[fv] += occur_aux[v];
  97.             if (nodes[v].str_idx != -1) {
  98.                 occur[nodes[v].str_idx] = occur_aux[v];
  99.                 ans += occur_aux[v];
  100.             }
  101.         }
  102.  
  103.         for (pair<int, int> x : rep) occur[x.first] = occur[x.second];
  104.         return ans;
  105.     }
  106. };
  107.  
  108. const int N = 1e4 + 7;
  109.  
  110. string v[N];
  111. int dp[N];
  112. queue<int> q;
  113.  
  114. int main() {
  115.     ios_base::sync_with_stdio(false);
  116.     cin.tie(nullptr);
  117.     int n;
  118.     while(cin >> n) {
  119.         if(!n) break;
  120.         vector<int> topo;
  121.         Aho<26> aho;
  122.         for(int i = 0; i < n; i++) {
  123.             dp[i] = 1;
  124.             cin >> v[i];
  125.         }
  126.         sort(v, v + n, [](string &a, string &b) {
  127.             return a.size() < b.size();
  128.         });
  129.         for(int i = 0; i < n; i++) {
  130.             aho.add(v[i]);
  131.         }
  132.         aho.build();
  133.         int ans = 0;
  134.         for(int i = 0; i < n; i++) {
  135.             aho.match(v[i]);
  136.             for(int j = 0; j < i; j++) {
  137.                 if(aho.occur[j]) {
  138.                     dp[i] = max(dp[i], dp[j] + 1);
  139.                 }
  140.             }
  141.             ans = max(ans, dp[i]);
  142.         }
  143.         cout << ans << "\n";
  144.     }
  145.     return 0;
  146. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement