<p>We define <code>str = [s, n]</code> as the string <code>str</code> which consists of the string <code>s</code> concatenated <code>n</code> times.</p>

<ul>
	<li>For example, <code>str == [&quot;abc&quot;, 3] ==&quot;abcabcabc&quot;</code>.</li>
</ul>

<p>We define that string <code>s1</code> can be obtained from string <code>s2</code> if we can remove some characters from <code>s2</code> such that it becomes <code>s1</code>.</p>

<ul>
	<li>For example, <code>s1 = &quot;abc&quot;</code> can be obtained from <code>s2 = &quot;ab<strong><u>dbe</u></strong>c&quot;</code> based on our definition by removing the bolded underlined characters.</li>
</ul>

<p>You are given two strings <code>s1</code> and <code>s2</code> and two integers <code>n1</code> and <code>n2</code>. You have the two strings <code>str1 = [s1, n1]</code> and <code>str2 = [s2, n2]</code>.</p>

<p>Return <em>the maximum integer </em><code>m</code><em> such that </em><code>str = [str2, m]</code><em> can be obtained from </em><code>str1</code>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<pre><strong>Input:</strong> s1 = "acb", n1 = 4, s2 = "ab", n2 = 2
<strong>Output:</strong> 2
</pre><p><strong class="example">Example 2:</strong></p>
<pre><strong>Input:</strong> s1 = "acb", n1 = 1, s2 = "acb", n2 = 1
<strong>Output:</strong> 1
</pre>
<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= s1.length, s2.length &lt;= 100</code></li>
	<li><code>s1</code> and <code>s2</code> consist of lowercase English letters.</li>
	<li><code>1 &lt;= n1, n2 &lt;= 10<sup>6</sup></code></li>
</ul>

class Solution {
    int mp[100][26] = {};
    int ending[100] = {};
public:
    int getMaxRepetitions(string s1, int n1, string s2, int n2) {
        int n = s1.size(), m = s2.size();
        for(int i = 0; i < n; i++)
            if(!mp[n - 1][s1[i] - 'a'])
                mp[n - 1][s1[i] - 'a'] = 1 + i;
        for(int i = n - 1; i > 0; i--)
            for(int j = 0; j < 26; j++)
                if(mp[i][j])
                    mp[i - 1][j] = 1 + (s1[i] == 'a' + j ? 0 : mp[i][j] % n);

        int s2_freq = 0, s1_rep = 0, s1_idx = n - 1, ans = 0;
        while(true){
            for(int i = 0; i < m; i++){
                if(!mp[s1_idx][s2[i] - 'a']) return 0;
                s1_idx += mp[s1_idx][s2[i] - 'a'];
                s1_rep += s1_idx / n;
                s1_idx %= n;
                if(s1_rep > n1) return (ans + s2_freq) / n2;
            }
            s2_freq++;

            if(ans) continue;

            if(ending[s1_idx]) {
                int interval = s1_rep - ending[s1_idx];
                ans = 1 + (n1 - ending[s1_idx]) / interval * (s2_freq - 1);
                s1_rep = n1 - (n1 - ending[s1_idx]) % interval;
                s2_freq = 0;
            }
            ending[s1_idx] = s1_rep;
        }
    }
};
8600