Cod sursa(job #1968982)

Utilizator andreigasparoviciAndrei Gasparovici andreigasparovici Data 18 aprilie 2017 07:27:10
Problema Potrivirea sirurilor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.58 kb
#include <fstream>
#include <vector>
#include <cstring>
using namespace std;
const int MAXN = 2049,  MAXM = 32001;
string text;
 
int n, m;
struct T{
    T* copii[52];
    int nr;
    T* fail;
    vector<T*> out;
    T(){
        nr = 0; 
        memset(copii, 0, sizeof(copii));
        fail = 0;
    }
}*root, *noduri[MAXM], *coada[10 * MAXM];
int inc, sf;

inline int poz(char c){
    if(c >= 'A' && c <='Z'){
        return c - 'A';
    }
    if(c >= 'a' && c <= 'z'){
        return c - 'a' + 26;
    }
    return -1;
}
 
T* ins(T*& nod, const char *p){
    if(!*p){
        
        return nod;
    }
    int pz = poz(*p);
    if(!nod->copii[pz]){
        nod->copii[pz] = new T; 
    }
    return ins(nod->copii[pz],  p + 1);
}
T* iter_ins(T* nod, const char *p){
    int len = strlen(p);
    for(int i = 0; i < len; i++){
        int pz = poz(p[i]);
        if(!nod->copii[pz])
            nod->copii[pz] = new T;
        nod = nod->copii[pz];
    }
    return nod;
}
 
void parcurg(T* nod){
    int len = nod->out.size();
    for(int i = 0; i < len; i++){
        parcurg(nod->out[i]);
        nod->nr += nod->out[i]->nr;
    }
}
 
string buffer;

inline void bfs(){
    coada[sf++] = root;
    while(inc != sf){
        T* nod = coada[inc++];
        for(int i = 0; i < 52; i++ ){
            if(!nod->copii[i])
                continue;
            T* f = nod->fail;
            while(f && !f->copii[i]){
                f = f->fail;
            }
 
            if(!f){
                nod->copii[i]->fail = root;
                root->out.push_back(nod->copii[i]);
            } else {
                nod->copii[i]->fail = f->copii[i];
                f->copii[i]->out.push_back(nod->copii[i]);
            }
 
            coada[sf++] = nod->copii[i];
             
        }
    }
}

inline void build_fail(){
    T* t = root;
    int s = text.size();
    for(int i = 0; i < s; i++){
        int ch = poz(text[i]);
        while(t && !t->copii[ch]){
            t = t->fail;
        }
 
        if(!t){
            t = root;
        } else {
            t = t->copii[ch];
        }
 
        t->nr++;
 
    }

}

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


inline void citire(){
   fin>>n;
 
    for(int i = 1; i <= n; i++){
        fin>>buffer;
        text += buffer;
    }
     
    fin>>m;
    for(int i = 1; i <= m ;i++){
        fin>>buffer;
        noduri[i] = iter_ins(root, buffer.c_str());
    }

}

int main(){
    root = new T;
    citire();     
        
    bfs();
    build_fail();
 
    parcurg(root);
    
    for(int i = 1; i <= m; i++){
        fout<<noduri[i]->nr<<'\n';
    }
    return 0;
}