1466GUnreviewed2600

Song of the Sirens

Progressive hints first, then the full explanation and implementation when you're ready to cash out.

Original problem

Review status

AI-generated and still unreviewed. Double-check the details before internalizing them.

Hints

Progressive nudges

Open only as much as you need to keep the solve alive.

Think about how the number of occurrences of tt in sis_i relates to the number in si1s_{i-1}. Since si=si1+ci+si1s_i = s_{i-1} + c_i + s_{i-1}, each copy of si1s_{i-1} contributes its own occurrences. What about new ones?

New occurrences of tt in sis_i can only appear at the "junction" — the region where the first si1s_{i-1}, the character cic_i, and the second si1s_{i-1} meet. Specifically, these are occurrences that overlap with cic_i. This gives f(i)=2f(i1)+g(i)f(i) = 2f(i-1) + g(i), where g(i)g(i) counts the crossing occurrences.

The junction region is: (last t1|t|-1 chars of si1s_{i-1}) + cic_i + (first t1|t|-1 chars of si1s_{i-1}). Observe that the prefix of sis_i equals the prefix of si1s_{i-1} (and transitively of s0s_0), and similarly the suffix. So once si1t1|s_{i-1}| \ge |t|-1, these prefix/suffix values stabilize, and g(i)g(i) depends only on cic_i.

After stabilization (level LL), you get f(k)=2f(k1)+g[ck]f(k) = 2f(k-1) + g[c_k] where g[α]g[\alpha] is precomputed for each character. Unrolling gives the closed form: f(w)=2wLf(L)+αg[α](Tα[w]2wLTα[L])f(w) = 2^{w-L} f(L) + \sum_{\alpha} g[\alpha]\bigl(T_\alpha[w] - 2^{w-L} T_\alpha[L]\bigr) where Tα[k]=j=1cj=αk2kjT_\alpha[k] = \sum_{\substack{j=1 \\ c_j=\alpha}}^{k} 2^{k-j} satisfies Tα[k]=2Tα[k1]+[ck=α]T_\alpha[k] = 2T_\alpha[k-1] + [c_k = \alpha].

Precompute Tα[k]T_\alpha[k] and 2k2^k (mod 109+710^9+7) for all kk and all 26 characters in O(26n)O(26n). For each query (w,t)(w, t): (1) find stabilization level LL by building sis_i until sit1|s_i| \ge |t|-1 (this is O(t)O(|t|) since sizes double), (2) compute f(L)f(L) via KMP on sLs_L, (3) compute g[α]g[\alpha] by counting tt in each junction string, (4) evaluate the closed-form in O(26)O(26). Total: O(26n+tj)O(26n + \sum|t_j|).

Key Observation

Since si=si1+ci+si1s_i = s_{i-1} + c_i + s_{i-1}, the count of occurrences of tt in sis_i satisfies:

f(i)=2f(i1)+g(i)f(i) = 2 \cdot f(i-1) + g(i)

where g(i)g(i) counts the new occurrences that cross the junction (i.e., they overlap with the inserted character cic_i).

Junction Analysis

The junction region is formed by the last t1|t|-1 characters of si1s_{i-1}, the character cic_i, and the first t1|t|-1 characters of si1s_{i-1}. This string has length 2t12|t|-1.

Critical insight: Any occurrence of tt (length t|t|) within a string of length 2t12|t|-1 must overlap the center character. So every occurrence found in the junction is genuinely new — none are double-counted from f(i1)f(i-1).

Prefix/Suffix Stabilization

Since sis_i starts with si1s_{i-1} (and transitively with s0s_0), and ends with si1s_{i-1} (and transitively with s0s_0), the prefix and suffix of sis_i of any fixed length stabilize quickly. Specifically, once sLt1|s_L| \ge |t|-1 for some level LL, the junction string at every subsequent level k>Lk > L is:

(last t1 chars of sL)+ck+(first t1 chars of sL)\text{(last } |t|-1 \text{ chars of } s_L\text{)} + c_k + \text{(first } |t|-1 \text{ chars of } s_L\text{)}

So g(k)g(k) depends only on the character ckc_k. We precompute g[α]g[\alpha] for each of the 26 possible characters by running KMP on the junction string.

Closed-Form via Decomposition

For k>Lk > L, the recurrence f(k)=2f(k1)+g[ck]f(k) = 2f(k-1) + g[c_k] unrolls to:

f(w)=2wLf(L)+j=L+1w2wjg[cj]f(w) = 2^{w-L} \cdot f(L) + \sum_{j=L+1}^{w} 2^{w-j} \cdot g[c_j]

Grouping by character α\alpha:

f(w)=2wLf(L)+αg[α](Tα[w]2wLTα[L])f(w) = 2^{w-L} \cdot f(L) + \sum_{\alpha} g[\alpha] \cdot \left(T_\alpha[w] - 2^{w-L} \cdot T_\alpha[L]\right)

where Tα[k]=j=1cj=αk2kjT_\alpha[k] = \sum_{\substack{j=1 \\ c_j = \alpha}}^{k} 2^{k-j} satisfies the recurrence Tα[k]=2Tα[k1]+[ck=α]T_\alpha[k] = 2 \cdot T_\alpha[k-1] + [c_k = \alpha].

Algorithm

  1. Precompute 2kmodp2^k \bmod p and Tα[k]modpT_\alpha[k] \bmod p for all k[0,n]k \in [0, n] and all 26 characters. Cost: O(26n)O(26n).

  2. Per query (w,t)(w, t) with t=m|t| = m:

    • Find stabilization level LL: build sis_i explicitly until sim1|s_i| \ge m-1 (at most O(logm)O(\log m) doublings, total string length O(m)O(m)).
    • If sw<m|s_w| < m: answer is 00.
    • Compute f(L)f(L) via KMP on sLs_L: O(m)O(m).
    • Compute g[α]g[\alpha] for each character via KMP on 26 junction strings: O(26m)O(26m).
    • Evaluate the closed-form formula: O(26)O(26).

Complexity

  • Precomputation: O(26n)O(26n)
  • Per query: O(m)O(m) where m=tm = |t|
  • Total: O(26n+27tj+26q)=O(n+tj+q)O(26n + 27\sum|t_j| + 26q) = O(n + \sum|t_j| + q) (ignoring the alphabet constant)

This comfortably handles n,q105n, q \le 10^5 and tj105\sum|t_j| \le 10^5.

#include <bits/stdc++.h>
using namespace std;

using ll = long long;

void setIO(const string& name = "") {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

#ifdef ZK_LOCAL_RUN
    freopen("f.in", "r", stdin);
    freopen("f.out", "w", stdout);
#else
    if (!name.empty()) {
        freopen((name + ".in").c_str(), "r", stdin);
        freopen((name + ".out").c_str(), "w", stdout);
    }
#endif
}

const int MOD = 1e9 + 7;

int kmpCount(const string& text, const string& pat) {
    int n = text.size(), m = pat.size();
    if (m == 0 || m > n) return 0;
    vector<int> fail(m, 0);
    for (int i = 1; i < m; i++) {
        int j = fail[i - 1];
        while (j > 0 && pat[i] != pat[j]) j = fail[j - 1];
        if (pat[i] == pat[j]) j++;
        fail[i] = j;
    }
    int cnt = 0, j = 0;
    for (int i = 0; i < n; i++) {
        while (j > 0 && text[i] != pat[j]) j = fail[j - 1];
        if (text[i] == pat[j]) j++;
        if (j == m) { cnt++; j = fail[j - 1]; }
    }
    return cnt;
}

int main() {
    setIO();
    int n, q;
    cin >> n >> q;
    string s0, c;
    cin >> s0 >> c;

    // Precompute pw[k] = 2^k mod MOD
    vector<ll> pw(n + 1);
    pw[0] = 1;
    for (int i = 1; i <= n; i++) pw[i] = pw[i - 1] * 2 % MOD;

    // T[a][k] = sum_{j=1..k, c[j-1]=='a'+a} 2^{k-j} mod MOD
    // Recurrence: T[a][k] = 2*T[a][k-1] + (c[k-1]-'a'==a)
    vector<vector<ll>> T(26, vector<ll>(n + 1, 0));
    for (int a = 0; a < 26; a++)
        for (int k = 1; k <= n; k++)
            T[a][k] = (2 * T[a][k - 1] + (c[k - 1] - 'a' == a)) % MOD;

    while (q--) {
        int w;
        string t;
        cin >> w >> t;
        int m = (int)t.size();

        // Find stabilization level L: smallest i with |s_i| >= m-1
        // Build s_i explicitly until that happens (or we reach level w)
        int L = -1;
        string cur = s0;

        if ((int)cur.size() >= m - 1) {
            L = 0;
        } else {
            for (int i = 1; i <= w; i++) {
                cur = cur + c[i - 1] + cur;
                if ((int)cur.size() >= m - 1) {
                    L = i;
                    break;
                }
            }
        }

        if (L == -1) {
            // |s_w| < m, pattern t cannot occur
            cout << 0 << "\n";
            continue;
        }

        string& sL = (L == 0) ? s0 : cur;
        ll fL = kmpCount(sL, t) % MOD;

        if (w == L) {
            cout << fL << "\n";
            continue;
        }

        // w > L: compute g[alpha] for each character using the stabilized prefix/suffix
        string pref, suf;
        if (m >= 2) {
            pref = sL.substr(0, m - 1);
            suf = sL.substr((int)sL.size() - (m - 1));
        }

        int g[26] = {};
        for (int a = 0; a < 26; a++) {
            string junc = suf + char('a' + a) + pref;
            g[a] = kmpCount(junc, t);
        }

        // f[w] = 2^{w-L} * fL + sum_a g[a] * (T[a][w] - 2^{w-L} * T[a][L])
        ll ans = pw[w - L] * fL % MOD;
        for (int a = 0; a < 26; a++) {
            if (!g[a]) continue;
            ll d = (T[a][w] - pw[w - L] * T[a][L] % MOD + MOD) % MOD;
            ans = (ans + (ll)g[a] % MOD * d) % MOD;
        }
        cout << ans << "\n";
    }
    return 0;
}