<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>

typedef long long ll;
const ll MOD = 1e9 + 7;
const ll BASE1 = 5689;
const ll BASE2 = 8861;
struct Hash {
    vector<pair<ll, ll>>hashes, po;
    //1 based indexing used
    Hash(const string &s) {
        hashes.assign(s.size() + 1, {1, 1}); 
        po.assign(s.size() + 1, {1, 1});
        for (ll i = 0; i < (ll)(s.size()); i++) {
            hashes[i + 1] = { (hashes[i].first * BASE1 + ((s[i] - 'a') + 1)) % MOD,
                              ( hashes[i].second * BASE2 + ((s[i] - 'a') + 1)) % MOD
                            };
            po[i + 1] = {(po[i].first * BASE1) % MOD,
                         (po[i].second * BASE2) % MOD
                        };
        }
    }

    //assuming inputs in 0 based index
    pair<ll, ll> g(ll l, ll r) {
        l++, r++; //comment this out if l and r are in 1 based index
        ll hash1 = (hashes[r].first - ( hashes[l - 1].first * po[r - l + 1].first) % MOD + MOD) % MOD;
        ll hash2 = (hashes[r].second - (hashes[l - 1].second * po[r - l + 1].second) % MOD + MOD) % MOD;
        return {hash1, hash2};
    }

};


class Solution {
public:
    long long sumScores(string s) {
        Hash shash(s);
        ll ans = 0, n = s.length();
        ans+=n;
        for(ll i = 1; i<n; i++){
            ll low = n - i, high = n-1;
            ll temp = -1;
            while(low<=high){
                ll mid = (low+high)/2;
                if(shash.g(n-i, mid)==shash.g(0, mid-n+i)) temp = mid, low = mid + 1;
                else high = mid - 1;
            }
            // if(i==3) cout<<temp<<endl;
            // if(temp!=-1) cout<<i<<" "<<temp-(n-i)+1<<endl;
            if(temp!=-1) ans+=(temp-(n-i)+1);
        }
        return ans;
    }
};
68100