<p>You are <strong>building</strong> a string <code>s</code> of length <code>n</code> <strong>one</strong> character at a time, <strong>prepending</strong> each new character to the <strong>front</strong> of the string. The strings are labeled from <code>1</code> to <code>n</code>, where the string with length <code>i</code> is labeled <code>s<sub>i</sub></code>.</p>

<ul>
	<li>For example, for <code>s = &quot;abaca&quot;</code>, <code>s<sub>1</sub> == &quot;a&quot;</code>, <code>s<sub>2</sub> == &quot;ca&quot;</code>, <code>s<sub>3</sub> == &quot;aca&quot;</code>, etc.</li>
</ul>

<p>The <strong>score</strong> of <code>s<sub>i</sub></code> is the length of the <strong>longest common prefix</strong> between <code>s<sub>i</sub></code> and <code>s<sub>n</sub></code> (Note that <code>s == s<sub>n</sub></code>).</p>

<p>Given the final string <code>s</code>, return<em> the <strong>sum</strong> of the <strong>score</strong> of every </em><code>s<sub>i</sub></code>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> s = &quot;babab&quot;
<strong>Output:</strong> 9
<strong>Explanation:</strong>
For s<sub>1</sub> == &quot;b&quot;, the longest common prefix is &quot;b&quot; which has a score of 1.
For s<sub>2</sub> == &quot;ab&quot;, there is no common prefix so the score is 0.
For s<sub>3</sub> == &quot;bab&quot;, the longest common prefix is &quot;bab&quot; which has a score of 3.
For s<sub>4</sub> == &quot;abab&quot;, there is no common prefix so the score is 0.
For s<sub>5</sub> == &quot;babab&quot;, the longest common prefix is &quot;babab&quot; which has a score of 5.
The sum of the scores is 1 + 0 + 3 + 0 + 5 = 9, so we return 9.</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> s = &quot;azbazbzaz&quot;
<strong>Output:</strong> 14
<strong>Explanation:</strong> 
For s<sub>2</sub> == &quot;az&quot;, the longest common prefix is &quot;az&quot; which has a score of 2.
For s<sub>6</sub> == &quot;azbzaz&quot;, the longest common prefix is &quot;azb&quot; which has a score of 3.
For s<sub>9</sub> == &quot;azbazbzaz&quot;, the longest common prefix is &quot;azbazbzaz&quot; which has a score of 9.
For all other s<sub>i</sub>, the score is 0.
The sum of the scores is 2 + 3 + 9 = 14, so we return 14.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= s.length &lt;= 10<sup>5</sup></code></li>
	<li><code>s</code> consists of lowercase English letters.</li>
</ul>

class Solution {
public:
    long long sumScores(string s) {
        int n = s.length();
        vector<long long> hash1(n), hash2(n), p_pow1(n), p_pow2(n);

        auto rolling_hash = [&] (vector<long long> &hash, long long p, long long M, vector<long long> &p_pow) {
            hash[0] = s[0] - 'a' + 1; p_pow[0] = 1;
            for (int i = 1; i < n; i++) {
                hash[i] = (hash[i - 1] * p % M + s[i] - 'a' + 1) % M;
                p_pow[i] = p_pow[i - 1] * p % M;
            }
        };

        auto sub_hash = [&] (int l, int r, vector<long long> &hash, long long M, vector<long long> &p_pow) {
            if (l == 0) return hash[r];
            return ((hash[r] - hash[l - 1] * p_pow[r - l + 1]) % M + M) % M;
        };

        rolling_hash(hash1, 31LL, 999999929LL, p_pow1);
        rolling_hash(hash2, 37LL, 999999937LL, p_pow2);

        auto checker = [&] (int x, int i) {
            if (!x) return true;
            int l1 = i, r1 = i + x - 1, l2 = 0, r2 = x - 1;
            int a = sub_hash(l1, r1, hash1, 999999929LL, p_pow1);
            int b = sub_hash(l1, r1, hash2, 999999937LL, p_pow2);
            int c = sub_hash(l2, r2, hash1, 999999929LL, p_pow1);
            int d = sub_hash(l2, r2, hash2, 999999937LL, p_pow2);

            if (a == c && b == d) return true;
            else return false;
        };

        long long x = 0;
        for (int i = n - 1; i >= 0; i--) {
            int sz = n - i, lo = 0, hi = sz + 1, mi;
            while (hi - lo > 1) {
                mi = lo + (hi - lo ) / 2;
                if (checker(mi, i)) lo = mi;
                else hi = mi;
            }
            x += lo * 1LL;
        }
        return x;
    }
};
68600