Cod sursa(job #3040202)

Utilizator stefan05Vasilache Stefan stefan05 Data 29 martie 2023 15:11:57
Problema Potrivirea sirurilor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.55 kb
#include <fstream>
#include <iostream>
#include <vector>

#define ALFMAX 58
#define NMAX 10005
#define SMAX 20005
#define VFMAX 600005
#define INF 1000000005

using namespace std;

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

int n, m;
int t; int x;
char s[NMAX][SMAX];
int dp[VFMAX][22];
int vfcount;
int send[NMAX];
vector<pair<int, int>> euler;
int first[VFMAX*2];
int i, j, q;

class Trie
{
private:
    int cnt = 0;
    Trie *next[ALFMAX] = {};
    char low = 'A';
    int vf = 0;
    int lvl = 0;

public:
    void _insert(const char s[], int pos = 0)
    {
        if (!s[pos])
        {
            cnt++;
            send[i] = vf;
            return;
        }

        if (!next[s[pos]-low])
        {
            next[s[pos]-low] = new Trie;
            next[s[pos]-low]->vf = ++vfcount;
            next[s[pos]-low]->lvl = lvl+1;
        }

        next[s[pos]-low]->_insert(s, pos+1);
    }

    void dfs()
    {
        int i;
        first[vf] = euler.size();
        euler.push_back({vf, lvl});
        for (i = 0; i < ALFMAX; ++i)
            if (next[i])
            {
                next[i]->dfs();
                euler.push_back({vf, lvl});
            }
    }
};

Trie trie;
int lca(int, int);

int log[VFMAX*2];

int main()
{
    for (i = 2; i < VFMAX*2; ++i)
        log[i] = log[i/2]+1;

    fin >>n>>m;
    for (i = 1; i <= n; ++i)
    {
        fin >>s[i];
        trie._insert(s[i]);
        //fout <<send[i]<<'\n';
    }

    trie.dfs();
    /*fout <<'\n';
    for (auto i: euler) fout <<i.first<<' '<<i.second<<'\n';*/

    for (i = 0; i < euler.size(); ++i)
        dp[i][0] = i;

    int l, r;
    for (j = 1; (1<<j) <= euler.size(); ++j)
        for (i = 0; i+(1<<j)-1 < euler.size(); ++i)
        {
            l = dp[i][j-1];
            r = dp[i+(1<<(j-1))][j-1];

            dp[i][j] = (euler[l].second < euler[r].second? l: r);
        }

    int maxim, minim;
    for (t = 1; t <= m; ++t)
    {
        fin >>q;
        maxim = -1; minim = INF;
        for (i = 1; i <= q; ++i)
        {
            fin >>x;
            maxim = max(maxim, first[send[x]]);
            minim = min(minim, first[send[x]]);
        }

        if (maxim == minim) fout <<euler[maxim].second<<'\n';
        else
            fout <<lca(minim, maxim)<<'\n';
    }
    fout.close();
    return 0;
}

int lca(int x, int y)
{
    int lg = log[y-x+1];
    int l = dp[x][lg];
    int r = dp[y-(1<<lg)+1][lg];
    return min(euler[l].second, euler[r].second);
}