Cod sursa(job #2729712)

Utilizator popashtefan10Popa Stefan popashtefan10 Data 25 martie 2021 10:07:49
Problema Trie Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.93 kb
/// alphabet reduction

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

using namespace std;

const int LMAX = 60;
const int SIGMA = 3;

struct nod {
  int nr_ap, capat;
  nod *fii[SIGMA];

  nod() : nr_ap(0), capat(0) {
    for(int i = 0; i < SIGMA; i++)
      fii[i] = nullptr;
  }
};

void add_cuv(nod *crt, int *cuv, int l) {
  crt->nr_ap++;
  if(l == 0)
    crt->capat++;
  else {
    if(!crt->fii[cuv[0]])
      crt->fii[cuv[0]] = new nod;
    add_cuv(crt->fii[cuv[0]], cuv + 1, l - 1);
  }
}

void del_cuv(nod *crt, int *cuv, int l) {
  crt->nr_ap--;
  if(l == 0)
    crt->capat--;
  else {
    del_cuv(crt->fii[cuv[0]], cuv + 1, l - 1);
    if(crt->fii[cuv[0]]->nr_ap == 0) {
      delete crt->fii[cuv[0]];
      crt->fii[cuv[0]] = nullptr;
    }
  }
}

int get_nr_ap(nod *crt, int *cuv, int l) {
  if(l == 0)
    return crt->capat;
  if(!crt->fii[cuv[0]])
    return 0;
  return get_nr_ap(crt->fii[cuv[0]], cuv + 1, l - 1);
}

int get_longest_prefix(nod *crt, int *cuv, int l) {
  if(l == 0 || !crt->fii[cuv[0]])
    return 1;
  return 1 + get_longest_prefix(crt->fii[cuv[0]], cuv + 1, l - 1);
}

void char_to_b3(char *src, int *dest) {
  for(int i = strlen(src) - 1; i >= 0; i--)
    for(int j = 2, p3 = 1; j >= 0; j--, p3 *= 3)
      dest[3 * i + j] = ((src[i] - 'a') / p3) % 3;
}

int main() {
  freopen("trie.in", "r", stdin);
  freopen("trie.out", "w", stdout);
  int op;
  char cuv[LMAX / 3 + 1];
  int cuvb3[LMAX + 1];
  nod *trie_root = new nod;

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

  return 0;
}