Advertisement
cosenza987

Untitled

Jun 21st, 2023
713
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.18 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.     }
  75.  
  76.     int match(string& s) {
  77.         if (!cnt) return 0;
  78.         if (!build_done) build();
  79.  
  80.         ans = 0;
  81.         occur = vector<int>(cnt);
  82.         occur_aux = vector<int>(nodes.size());
  83.  
  84.         int u = 0;
  85.         for (char ch : s) {
  86.             int c = remap(ch);
  87.             u = nodes[u].nxt[c];
  88.             occur_aux[u]++;
  89.         }
  90.  
  91.         for (int i = (int)ord.size() - 1; i >= 0; i--) {
  92.             int v = ord[i];
  93.             int fv = nodes[v].link;
  94.             occur_aux[fv] += occur_aux[v];
  95.             if (nodes[v].str_idx != -1) {
  96.                 occur[nodes[v].str_idx] = occur_aux[v];
  97.                 ans += occur_aux[v];
  98.             }
  99.         }
  100.  
  101.         for (pair<int, int> x : rep) occur[x.first] = occur[x.second];
  102.         return ans;
  103.     }
  104. };
  105.  
  106. int main() {
  107.     ios_base::sync_with_stdio(false);
  108.     cin.tie(nullptr);
  109.     int n;
  110.     while(cin >> n) {
  111.         if(!n) break;
  112.         vector<string> v(n);
  113.         vector<vector<int>> adj(n);
  114.         vector<int> in(n), topo, dist(n, 1);
  115.         Aho<26> aho;
  116.         for(int i = 0; i < n; i++) {
  117.             cin >> v[i];
  118.             aho.add(v[i]);
  119.         }
  120.         aho.build();
  121.         for(int i = 0; i < n; i++) {
  122.             aho.match(v[i]);
  123.             for(int j = 0; j < n; j++) {
  124.                 if(i != j and aho.occur[j]) {
  125.                     adj[j].push_back(i);
  126.                     in[i]++;
  127.                 }
  128.             }
  129.         }
  130.         queue<int> q;
  131.         for(int i = 0; i < n; i++) {
  132.             if(!in[i]) {
  133.                 q.push(i);
  134.             }
  135.             if(!adj[i].size()) dist[i] = 1;
  136.         }
  137.         while(!q.empty()) {
  138.             int x = q.front(); q.pop();
  139.             topo.push_back(x);
  140.             for(auto e : adj[x]) {
  141.                 if(in[e] > 0 and --in[e] == 0) {
  142.                     q.push(e);
  143.                 }
  144.             }
  145.         }
  146.         reverse(topo.begin(), topo.end());
  147.         for(auto e : topo) {
  148.             for(auto i : adj[e]) {
  149.                 dist[e] = max(dist[e], dist[i] + 1);
  150.             }
  151.         }
  152.         cout << *max_element(dist.begin(), dist.end()) << "\n";
  153.     }
  154.     return 0;
  155. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement