Cod sursa(job #2744490)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 24 aprilie 2021 19:07:56
Problema Aho-Corasick Scor 90
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.07 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

struct node {
  node* k[26];
  node* to;
  vector<int> ids;
  int sol;
 /// string val; /// delete later;
  node() {
    for (int i = 0; i < 26; i++) {
      k[i] = 0;
    }
    to = 0;
    ///ids.clear();
   ///val = "";
    sol = 0;
  }
};

void print(node* a) {
  ///cout << a->val << "\n";
  for (int i = 0; i < 26; i++) {
    if (a->k[i]) {
      print(a->k[i]);
    }
  }
}

node* root = new node;
int sol[123];

int main() {
  freopen ("ahocorasick.in", "r", stdin);
  freopen ("ahocorasick.out", "w", stdout);

  string str;
  cin >> str;
  int n;
  cin >> n;
  for (int i = 1; i <= n; i++) {
    string s;
    cin >> s;
    node* cur = root;
    for (auto &ch : s) {
      int x = ch - 'a';
      if (!cur->k[x]) {
        cur->k[x] = new node;
      ///  cur->k[x]->val = cur->val + ch;
      }
      cur = cur->k[x];
    }
    cur->ids.push_back(i);
  }
  queue<node*> q;
  vector<node*> ord;
  q.push(root);
  while (!q.empty()) {
    node* cur = q.front();
    q.pop();
    ord.push_back(cur);
    for (int i = 0; i < 26; i++) {
      if (cur->k[i]) {
        q.push(cur->k[i]);
      }
    }
  }
  root->to = root;
  for (auto &cur : ord) {
    for (int i = 0; i < 26; i++) {
      if (cur->k[i]) {
        node* now = cur->to;
        while (now != root && !now->k[i]) {
          now = now->to;
        }
        if (cur != root && now->k[i]) {
          now = now->k[i];
        }
        cur->k[i]->to = now;
      }
    }
  }
  node* cur = root;
  for (auto &ch : str) {
    int i = ch - 'a';
    while (cur != root && !cur->k[i]) {
      cur = cur->to;
    }
    if (cur->k[i]) {
      cur = cur->k[i];
    }
    cur->sol++;
  }
  reverse(ord.begin(), ord.end());
  for (auto &cur : ord) {
    cur->to->sol += cur->sol;
    for (auto &ind : cur->ids) {
      sol[ind] += cur->sol;
    }
  }
  for (int i = 1; i <= n; i++) {
    cout << sol[i] << "\n";
  }
  return 0;
}