Cod sursa(job #3201298)

Utilizator PowerPlantNICOLAS ANDREI MANASIA PowerPlant Data 7 februarie 2024 15:42:32
Problema ADN Scor 60
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.23 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin ("adn.in");
ofstream fout ("adn.out");
int const mod1 = 666013;
bool v[20];
string s[20];
vector <int> V, A;
long long Hash1[20][30030];
int C[20][20], pi[30030], prec[20][(1 << 19) + 10];
long long dp[20][(1 << 19) + 10];
int n;

long long put(long long A, int N, int mod)
{
    long long P = 1;
    for(int k = 1; k <= N; k <<= 1)
    {
        if( (N & k) )
            P = P * A % mod;
        A = A * A % mod;
    }
    return P;
}

long long inv_mod(int A, int mod){
    return put(A, mod - 2, mod);
}

long long get_end_Hash1(int i, int Poz)
{
    long long H = (Hash1[i][s[i].size() - 1] - Hash1[i][s[i].size() - 1 - Poz - 1]) * inv_mod(put(27, s[i].size() - Poz - 1, mod1), mod1) % mod1;
    return H;
}

void DFS(int node, int config)
{
    for(auto it : V)
        if(( (1 << it) & config) == 0 && dp[it][config + (1 << it)] < dp[node][config] + C[node][it])
        {
            dp[it][config + (1 << it)] = dp[node][config] + C[node][it];
            prec[it][config + (1 << it)] = node;
            DFS(it, config + (1 << it));
        }
}


int main()
{
    fin >> n;
    for(int i = 1; i <= n; ++i)
    {
        fin >> s[i];
        Hash1[i][0] = s[i][0];
        for(int j = 1; j < s[i].size(); ++j)
        {
            Hash1[i][j] = (Hash1[i][j - 1] + s[i][j] * put(27, j, mod1)) % mod1;
        }
    }

    for(int i = 1; i < n; ++i)
        for(int j = i + 1; j <= n; ++j)
        {
            int x, y;
            if(s[i].size() <= s[j].size())
                x = i, y = j;
            else x = j, y = i;
            long long H = Hash1[x][s[x].size() - 1];
            for(int e = 0; e <= s[y].size() - s[x].size(); ++e)
            {
                long long h = (Hash1[y][e + s[x].size() - 1] - Hash1[y][e - 1]) * inv_mod(put(27, e, mod1), mod1) % mod1;
                if(h == H)
                    v[x] = 1;
            }
        }
    long long conf = 0;
    for(int i = 1; i <= n; ++i)
        if(v[i] == 0)
            V.push_back(i), conf = conf + (1 << i);

    for(auto i : V)
        for(auto j : V)
            if(i != j)
            {
                string S = "@" + s[i] + "$" + s[j];
                int k = 0;
                pi[1] = 0;
                for(int e = 2; e < S.size(); ++e)
                {
                    while(k != 0 && S[k + 1] != S[e])
                        k = pi[k];
                    if(S[k + 1] == S[e])
                        ++k;
                    pi[e] = k;
                }
                C[j][i] = pi[S.size() - 1];
            }


    for(auto i : V)
        DFS(i, (1 << i));
    long long ans = 0;
    int poz = 0;
    for(auto i : V){
        if(ans < dp[i][conf]) poz = i;
        ans = max(ans, dp[i][conf]);
    }
    A.push_back(poz);

    while(conf != 0)
    {
        int aux = prec[poz][conf];
        conf -= (1 << poz);
        poz = aux;
        if(conf != 0) A.push_back(poz);
    }

    for(int i = A.size() - 1; i > 0; --i)
        for(int j = 0; j <= s[A[i]].size() - 1 - C[A[i]][A[i - 1]]; ++j)
            fout << s[A[i]][j];
    for(int j = 0; j <= s[A[0]].size(); ++j)
        fout << s[A[0]][j];
    return 0;
}