Cod sursa(job #1515607)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 1 noiembrie 2015 21:49:12
Problema Trie Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.32 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cstdlib>

using namespace std;

const int kMaxLen = 20;
const int kMalloc = 2048;

struct Trie {
  vector <pair <char, Trie* > > next;
  unsigned short contor;
  Trie() {
    contor = 0;
  }
};

Trie *Root;
Trie *preAlloc;
int pPos = kMalloc;

inline Trie* alloc() {
  if (pPos == kMalloc) {
    preAlloc = new Trie[kMalloc];
    pPos = 0;
  }
  return &preAlloc[pPos++];
}

void trieInsert(Trie* &node, char *s) {
  if (*s == '\0') {
    node->contor++;
  } else {
    unsigned i = 0;
    while ((i < node->next.size()) && (node->next[i].first != *s)) {
      i++;
    }
    if (i == node->next.size()) {
      node->next.emplace_back(make_pair(*s, alloc()));
    }
    trieInsert(node->next[i].second, s + 1);
  }
}

bool trieErase(Trie* &node, char *s) {
  if (*s == '\0') {
    if (node->contor) {
      node->contor--;
      return 1;
    }
  } else {
    unsigned i = 0;
    while ((i < node->next.size()) && (node->next[i].first != *s)) {
      i++;
    }
    if (i != node->next.size()) {
      Trie *son = node->next[i].second;
      if (trieErase(son, s + 1) && !son->contor && son->next.empty()) {
        node->next.erase(node->next.begin() + i);
	//delete son;
        return 1;
      }
    }
  }
  return 0;
}

int trieQuery(Trie* node, char *s) {
  if (*s == 0) {
    return node->contor;
  } else {
    unsigned i = 0;
    while ((i < node->next.size()) && (node->next[i].first != *s)) {
      i++;
    }
    if (i != node->next.size()) {
      return trieQuery(node->next[i].second, s + 1);
    }
    return 0;
  }
}

int triePrefix(Trie *node, char *s) {
  if (*s == '\0') {
    return 0;
  } else {
    unsigned i = 0;
    while ((i < node->next.size()) && (node->next[i].first != *s)) {
      i++;
    }
    if (i != node->next.size()) {
      return 1 + triePrefix(node->next[i].second, s + 1);
    }
    return 0;
  }
}

int main(void) {
  ifstream in("trie.in");
  ofstream out("trie.out");
  int opType;
  char s[kMaxLen + 1];

  Root = new Trie;
  
  while (in >> opType >> s) {
    if (opType == 0) {
      trieInsert(Root, s);
    } else if (opType == 1) {
      trieErase(Root, s);
    } else if (opType == 2) {
      out << trieQuery(Root, s) << '\n';
    } else {
      out << triePrefix(Root, s) << '\n';
    }
  }
  in.close();
  out.close();
  return 0;
}