Cod sursa(job #2931354)

Utilizator flibiaVisanu Cristian flibia Data 30 octombrie 2022 22:31:59
Problema Trie Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.1 kb
#include <bits/stdc++.h>

using namespace std;
 
#ifdef LOCAL
#include "debug.h"
#else
#define dbg(...) 69
#define nl(...) 42
#endif

#define ll long long
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
ll random(ll st, ll dr) {
    assert(st <= dr);
    return st + rng() % (dr - st + 1);
}

const int MOD = 1e9 + 7;
const int N = 2e5 + 10;
const int ALPHA = 26;

struct Node {
    int allocatedSons;
    int wordEnds;

    Node* sons[ALPHA];

    Node() : allocatedSons(0), wordEnds(0) {
        for (int i = 0; i < ALPHA; i++) {
            sons[i] = nullptr;
        }
    }
};

int decode(char c) {
    return c - 'a';
}

void add(Node* root, string& word, int pos) {
    if (pos == word.size()) {
        root->wordEnds++;
        return;
    }

    int id = decode(word[pos]);
    if (!(root->sons[id])) {
        root->sons[id] = new Node();
        root->allocatedSons++;
    }
    add(root->sons[id], word, pos + 1);
}

bool canRemove(Node *root, string& word, int pos) {
    if (pos == word.size()) {
        root->wordEnds--;
        return root->allocatedSons == 0 && root->wordEnds == 0;
    }

    int id = decode(word[pos]);
    bool ok = canRemove(root->sons[id], word, pos + 1);
    if (ok) {
        delete root->sons[id];
        root->allocatedSons--;
        root->sons[id] = nullptr;
    }

    return root->allocatedSons == 0 && root->wordEnds == 0;
}

int countAppearances(Node* root, string& word, int pos) {
    if (!root) {
        return 0;
    }

    if (pos == word.size()) {
        return root->wordEnds;
    }

    return countAppearances(root->sons[decode(word[pos])], word, pos + 1);
}

int longestPrefix(Node *root, string& word, int pos) {
    if (pos == word.size()) {
        return 0;
    }

    int id = decode(word[pos]);
    if (root->sons[id]) {
        return 1 + longestPrefix(root->sons[id], word, pos + 1);
    } else {
        return 0;
    }
}

void solve(int test, istream &cin, ostream &cout) {
    int cod;
    string s;

    Node* root = new Node();
    
    while (cin >> cod >> s) {
        switch (cod) {
            case 0:
                add(root, s, 0);
                break;
            case 1:
                canRemove(root, s, 0);
                break;
            case 2:
                cout << countAppearances(root, s, 0) << '\n';
                break;
            case 3:
                cout << longestPrefix(root, s, 0) << '\n';
                break;
            default:
                ;
        }
    }
}

int main() {
    ifstream cin("trie.in");
    ofstream cout("trie.out");
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    auto start = std::chrono::high_resolution_clock::now();

    bool multiTest = false;

    int t;    
    if (multiTest) {
        cin >> t;
    } else {
        t = 1;
    }

    for (int test = 1; test <= t; test++) {
        solve(test, cin, cout);
    }

    auto stop = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
    // cerr << fixed << setprecision(6) << "Running time: " << (double) duration.count() / 1e6 << " seconds" << '\n';

    return 0;
}