Cod sursa(job #2589296)

Utilizator CyborgSquirrelJardan Andrei CyborgSquirrel Data 26 martie 2020 08:14:05
Problema Aho-Corasick Scor 95
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.87 kb
#include <iostream>
#include <fstream>
#include <string>
#include <unordered_map>
#include <queue>
#include <vector>

#include <chrono>

using namespace std;

ifstream fin("ahocorasick.in");
ofstream fout("ahocorasick.out");

struct nod;
nod *r;

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

int frecc[114];
struct nod{
    nod *ch[27];
    nod *suf = NULL, *dsuf = NULL;
    vector<int> indices;
    void add(const string &a, int index){
        nod *p = this;
        for(auto c : a){
            int ci = cv(c);
            if(p->ch[ci] == NULL){
                p->ch[ci] = new nod();
            }
            p = p->ch[ci];
        }
        p->indices.push_back(index);
    }
    void upgrade(){
        queue<nod*> qu;
        qu.push(this);
        while(!qu.empty()){
            nod *p = qu.front();
            qu.pop();
            for(int ci = 0; ci < 26; ++ci){
                nod *q = p->ch[ci];

                if(q != NULL){
                    q->suf = p->suf;
                    while(q->suf != NULL && q->suf->ch[ci] == NULL){
                        q->suf = q->suf->suf;
                    }

                    if(q->suf == NULL){
                        q->suf = r;
                    }else{
                        q->suf = q->suf->ch[ci];
                    }

                    qu.push(q);
                }
            }
        }
    }
    void upgrade2(){
        queue<nod*> qu;
        qu.push(this);
        while(!qu.empty()){
            nod *p = qu.front();
            qu.pop();
            for(int ci = 0; ci < 26; ++ci){
                nod *q = p->ch[ci];

                if(q != NULL){
                    q->dsuf = q->suf;
                    while(q->dsuf != NULL && q->dsuf->indices.empty()){
                        q->dsuf = q->dsuf->suf;
                    }
                    qu.push(q);
                }
            }
        }
    }
    nod *next(char c){
        int ci = cv(c);
        nod *p = this;
        while(p->suf != NULL && p->ch[ci] == NULL){
            p = p->suf;
        }

        if(p->ch[ci] == NULL){
            return r;
        }else{
            return p->ch[ci];
        }
    }
    void addme(){
        for(auto index : indices){
            frecc[index]++;
        }
    }
};

int n;
string s, a;
void read(){
    r = new nod();
    fin >> s >> n;
    for(int i = 1; i <= n; ++i){
        fin >> a;
        r->add(a, i);
    }
}

void solve(){
    r->upgrade();
    r->upgrade2();
    nod *p = r;
    for(auto c : s){
        p = p->next(c);
        nod *q = p;
        while(q != NULL){
            q->addme();
            q = q->dsuf;
        }
    }
}

void write(){
    for(int i = 1; i <= n; ++i){
        fout << frecc[i] << "\n";
    }
}

int main(){
    read();
    solve();
    write();
    return 0;
}