Cod sursa(job #2730176)

Utilizator popashtefan10Popa Stefan popashtefan10 Data 25 martie 2021 21:20:48
Problema Trie Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.73 kb
/// left-child right-sibling tree, memorie alocata static

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int LMAX = 20;
const int SIGMA = 3;
const int NROP = 100000;

struct nod {
  char ch;
  int nr_ap, capat;
  int child_idx, sibling_idx;
};

nod trie[NROP * LMAX + 5];
int last_added = -1;

void add_cuv(int nod_idx, char *cuv, int l) {
  nod &crt = trie[nod_idx];

  crt.nr_ap++;
  if(l == 0)
    crt.capat++;
  else {
    int last_child = -1;
    for(int child_idx = crt.child_idx; child_idx != -1; child_idx = trie[child_idx].sibling_idx) {
      last_child = child_idx;
      if(trie[child_idx].ch == cuv[0]) {
        add_cuv(child_idx, cuv + 1, l - 1);
        return;
      }
    }

    trie[++last_added].ch = cuv[0];
    trie[last_added].nr_ap = trie[last_added].capat = 0;
    trie[last_added].child_idx = trie[last_added].sibling_idx = -1;
    if(last_child == -1) {
      crt.child_idx = last_added;
      add_cuv(crt.child_idx, cuv + 1, l - 1);
    }
    else {
      trie[last_child].sibling_idx = last_added;
      add_cuv(last_added, cuv + 1, l - 1);
    }
  }
}

void del_cuv(int nod_idx, char *cuv, int l) {
  nod &crt = trie[nod_idx];

  crt.nr_ap--;
  if(l == 0)
    crt.capat--;
  else
    for(int child_idx = crt.child_idx; child_idx != -1; child_idx = trie[child_idx].sibling_idx)
      if(trie[child_idx].ch == cuv[0]) {
        del_cuv(child_idx, cuv + 1, l - 1);
        return;
      }
}

int get_nr_ap(int nod_idx, char *cuv, int l) {
  nod &crt = trie[nod_idx];

  if(l == 0)
    return crt.capat;
  for(int child_idx = crt.child_idx; child_idx != -1; child_idx = trie[child_idx].sibling_idx)
    if(trie[child_idx].ch == cuv[0])
      return get_nr_ap(child_idx, cuv + 1, l - 1);
  return 0;
}

int get_longest_prefix(int nod_idx, char *cuv, int l) {
  nod &crt = trie[nod_idx];

  if(crt.nr_ap == 0)
    return 0;
  for(int child_idx = crt.child_idx; child_idx != -1; child_idx = trie[child_idx].sibling_idx)
    if(trie[child_idx].ch == cuv[0])
      return 1 + get_longest_prefix(child_idx, cuv + 1, l - 1);
  return 1;
}

int main() {
  freopen("trie.in", "r", stdin);
  freopen("trie.out", "w", stdout);
  int op;
  char cuv[LMAX + 5];
  trie[++last_added].ch = '*';
  trie[last_added].nr_ap = trie[last_added].capat = 0;
  trie[last_added].child_idx = trie[last_added].sibling_idx = -1;

  while(scanf("%d %s ", &op, cuv) != EOF) {
    if(op == 0)
      add_cuv(0, cuv, strlen(cuv));
    else if(op == 1)
      del_cuv(0, cuv, strlen(cuv));
    else if(op == 2)
      printf("%d\n", get_nr_ap(0, cuv, strlen(cuv)));
    else
      printf("%d\n", get_longest_prefix(0, cuv, strlen(cuv)) - 1);
  }

  return 0;
}