Cod sursa(job #2146088)

Utilizator hasmasandragosHasmasan Dragos hasmasandragos Data 27 februarie 2018 19:43:47
Problema Ciclu Eulerian Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.47 kb
#include <bits/stdc++.h>
using namespace std;

/// idee: vom creea o trie imaginara a arborelui initial. ca 2 noduri din arborele initial sa fie palindroame, ele trebuie sa aiba aceeasi pozitie in trie

ifstream f("aiacupalindroame.in");
ofstream g("aiacupalindroame.out");

const int nmax = 100005;

vector <int> arbore[nmax];
int n, queries, trie_marker;
char dictionar[nmax]; /// dictionar[i] = litera care leaga nodul i+1 de tatal sau
int pozitieInTrie[nmax]; /// pozitia unui nod in tria imaginara

struct trie
{
    int eticheta;
    trie *fiu[30],*tata;

    trie()
    {
        eticheta = 0;
        tata = 0;
        memset(fiu,0,sizeof(fiu));
    }
};

trie *root = new trie();

void dfs_trie(int nodArbore, trie *nodTrie)
{
    int i, vecini, nodNou, literaFiuTrie, delta;
    vecini = arbore[nodArbore].size();

    for (i=0; i<vecini; i++) /// completare pozitie in trie pentru fii nodului curent
    {
        nodNou = arbore[nodArbore][i];
        literaFiuTrie = dictionar[nodNou-2]; /// dictionarul este decalat cu 2 pozitii (dic[i] = litera care leaga nodul i+1 de tatal sau)
        delta = literaFiuTrie - 'a';

        if (nodTrie->fiu[delta] == NULL) /// daca nu avem fiul nodului dorit
        {
            nodTrie->fiu[delta] = new trie(); /// creeam acel nod
            nodTrie->fiu[delta]->eticheta = ++trie_marker; /// si il etichetam
        }

        pozitieInTrie[nodNou] = nodTrie->fiu[delta]->eticheta; /// atribuim nodului nou din arborele intial pozitia sa in tria imaginara
    }

    for (i=0; i<vecini; i++) /// rezolvare si pentru fii nodului curent
    {
        nodNou = arbore[nodArbore][i];
        literaFiuTrie = dictionar[nodNou-2]; /// dictionarul este decalat cu 2 pozitii (dic[i] = litera care leaga nodul i+1 de tatal sau)
        delta = literaFiuTrie - 'a';
        dfs_trie(nodNou, nodTrie->fiu[delta]);
    }

}

int main()
{
    f>>n>>queries;

    /// citim arborele initial
    int nodParinte;
    for (int nodFiu = 2; nodFiu <= n; nodFiu++)
    {
        f>>nodParinte;
        arbore[nodParinte].push_back(nodFiu);
    }

    f>>dictionar;

    dfs_trie(1, root);

    int x,y;

    while (queries--) /// iteram intrebarile
    {
        f>>x>>y;
        if (pozitieInTrie[x] == pozitieInTrie[y]) /// daca doua noduri din arborele initial au aceeasi pozitie in trie, ele sunt "palindroame"
            g<<"1"<<'\n';
        else
            g<<"0"<<'\n';
    }

    return 0;
}