Inspired by these two questions: String manipulation: calculate the "similarity of a string with its suffixes" and Program execution varies as the I/P size increas
You might want to have a look at the Z-algorithm, that's provably linear:
s is a C-string of length N
Z[0] = N;
int a = 0, b = 0;
for (int i = 1; i < N; ++i)
{
int k = i < b ? min(b - i, Z[i - a]) : 0;
while (i + k < N && s[i + k] == s[k]) ++k;
Z[i] = k;
if (i + k > b) { a = i; b = i + k; }
}
Now similarity is just the sum of entries of Z.