Cod sursa(job #3353330)

Utilizator unomMirel Costel unom Data 6 mai 2026 10:42:37
Problema ADN Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.87 kb
#include <fstream>
#include <iostream>

using namespace std;

#define int long long

ifstream in("adn.in");
ofstream out("adn.out");
int n;
int sz[20];
int v[20][30005];
int pref[20][30005];
int useless[20];
int cost[20][20];
signed dp[20][262155];
signed last[20][262155];
int ans[550005];
int BAZA = 7;
int MOD = 1e9 + 9;
int INF = (1 << 30);

int tranform(char c)
{
    if(c == 'A') return 1;
    if(c == 'C') return 2;
    if(c == 'G') return 3;
    if(c == 'T') return 4;
}

char inv_transform(int x)
{
    if(x == 1) return 'A';
    if(x == 2) return 'C';
    if(x == 3) return 'G';
    if(x == 4) return 'T';
}

int lgput(int x, int e)
{
    int ans = 1;

    while(e != 0)
    {
        if(e % 2 == 1)
        {
            ans = (ans * x) % MOD;
        }

        x = (x * x) % MOD;
        e /= 2;
    }

    return ans;
}

int query(int ind, int st, int dr)
{
    int ans = (pref[ind][dr] - pref[ind][st - 1] + MOD) % MOD;
    ans = (ans * lgput(lgput(BAZA, st - 1), MOD - 2)) % MOD;

    return ans;
}

int contains_secv(int x, int y)
{
    if(sz[y] > sz[x])
    {
        return 0;
    }

    for(int i = 1; i<=sz[x] - sz[y] + 1; i++)
    {
        int dr = i + sz[y] - 1;
        if(query(y, 1, sz[y]) == query(x, i, dr))
        {
            return 1;
        }
    }

    return 0;
}

int same_pref_suf(int x, int y)
{
    int lmax = min(sz[x], sz[y]);

    int j = lmax;
    for(int i = sz[x] - lmax + 1; i<=sz[x]; i++)
    {
        if(query(x, i, sz[x]) == query(y, 1, j))
        {
            return j;
        }

        j--;
    }

    return 0;
}

signed main()
{
    in>>n;

    string s;
    for(int i = 0; i<n; i++)
    {
        in>>s;

        sz[i] = s.size();
        for(int j = 1; j<=sz[i]; j++)
        {
            v[i][j] = tranform(s[j - 1]);
        }

        int put = 1;
        for(int j = 1; j<=sz[i]; j++)
        {
            pref[i][j] = (pref[i][j - 1] + v[i][j] * put) % MOD;
            put = (put * BAZA) % MOD;
        }
    }

    for(int i = 0; i<n; i++)
    {
        for(int j = 0; j<n; j++)
        {
            if(i == j)
            {
                continue;
            }

            if(contains_secv(i, j) == 1)
            {
                useless[j] = 1;
            }
        }
    }

    for(int i = 0; i<n; i++)
    {
        if(useless[i] == 0)
        {
            continue;
        }

        swap(useless[i], useless[n - 1]);
        swap(sz[i], sz[n - 1]);
        swap(v[i], v[n - 1]);
        swap(pref[i], pref[n - 1]);

        n--;
        i--;
    }

//    for(int i = 0; i<n; i++)
//    {
//        for(int j = 0; j<n; j++)
//        {
//            if(i == j)
//            {
//                continue;
//            }
//
//            cost[i][j] = sz[j] - same_pref_suf(i, j);
////            cout<<i<<" "<<j<<" "<<same_pref_suf(i, j)<<'\n';
//        }
//    }
//
//    for(int i = 0; i<n; i++)
//    {
//        for(int mask = 0; mask < (1 << n); mask++)
//        {
//            dp[i][mask] = INF;
//        }
//    }
//
//    for(int i = 0; i<n; i++)
//    {
//        dp[i][(1 << i)] = sz[i];
//        last[i][(1 << i)] = -1;
//    }
//
//    for(int mask = 1; mask < (1 << n); mask++)
//    {
//        for(int i = 0; i<n; i++)
//        {
//            if(!(mask & (1 << i)))
//            {
//                continue;
//            }
//
//            for(int j = 0; j<n; j++)
//            {
//                if((mask & (1 << j)))
//                {
//                    continue;
//                }
//
//                if(dp[i][mask] + cost[i][j] < dp[j][mask | (1 << j)])
//                {
//                    dp[j][mask | (1 << j)] = dp[i][mask] + cost[i][j];
//                    last[j][mask | (1 << j)] = i;
//                }
//            }
//        }
//    }
//
//    int cur = 0;
//    int mask = (1 << n) - 1;
//    for(int i = 0; i<n; i++)
//    {
//        if(dp[i][(1 << n) - 1] < dp[cur][(1 << n) - 1])
//        {
//            cur = i;
//        }
//    }
//
//    int lmin = dp[cur][(1 << n) - 1];
//    int poz = lmin;
//
//    while(cur != -1)
//    {
//        int nxt = last[cur][mask];
//
//        if(nxt == -1)
//        {
//            for(int i = 1; i<=sz[cur]; i++)
//            {
//                ans[i] = v[cur][i];
//            }
//            break;
//        }
//
//        int nr_char = cost[nxt][cur];
//        int ind = sz[cur] - nr_char + 1;
//
//        for(int i = poz - nr_char + 1; i<=poz; i++)
//        {
//            ans[i] = v[cur][ind];
//            ind++;
//        }
//
//        poz -= nr_char;
//        mask ^= (1 << cur);
//        cur = nxt;
//    }
//
//    for(int i = 1; i<=lmin; i++)
//    {
//        out<<inv_transform(ans[i]);
//    }

    return 0;
}