Pagini recente » Cod sursa (job #3278656) | Cod sursa (job #40354) | Cod sursa (job #3282019) | Cod sursa (job #31817) | Cod sursa (job #3201298)
#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;
}