Untitled

 avatar
unknown
plain_text
a year ago
3.4 kB
4
Indexable
#include <bits/stdc++.h>

#define ll long long
#define stp(n) fixed<<setprecision(n)
#define flash cin.tie(0); cin.sync_with_stdio(0);
#define el '\n'
# define pll pair<ll,ll>
# define pi pair<int,int>
#define popCnt(x) (__builtin_popcountll(x))
#define LSB(x) (__builtin_ffsll(x) - 1)
#define MSB(x) (64 - __builtin_clzll(x) - 1).

using namespace std;

#pragma GCC optimize("03")
#pragma GCC target("tune=native")
#pragma GCC optimize("unroll-loops")

const ll mod = 1e9 + 7;

ll mul(const ll &a, const ll &b) {
    return (a % mod + mod) * (b % mod + mod) % mod;
}

ll add(const ll &a, const ll &b) {
    return (a + b + 2 * mod) % mod;
}

//const int N = 5e3 + 9, inf = 2e9;
//const ll infl = 2e18;


const int N = 1e5 + 10, base = 31, base2 = 27;

ll pw1[N], inv1[N];
ll pw2[N], inv2[N];

long long binP(long long a, long long b) {
    a %= mod;
    long long res = 1;
    while (b > 0) {
        if (b & 1)
            res = mul(res, a);
        a = mul(a, a);
        b >>= 1;
    }
    return res;
}

void pre() {
    pw1[0] = 1, inv1[0] = 1;
    pw2[0] = 1, inv2[0] = 1;
    for (int i = 1; i < N; i++) {
        //For single hash
        pw1[i] = mul(base, pw1[i - 1]);
        inv1[i] = binP(pw1[i], mod - 2);

        //For second hash
        pw2[i] = mul(base2, pw2[i - 1]);
        inv2[i] = binP(pw2[i], mod - 2);
    }
}

ll pref1[N];
ll pref2[N];

void generateHash(string &str) {
    for (int i = 0; i < str.size(); i++) {
        int idx = str[i] - 'a' + 1;


        pref1[i] = mul(idx, pw1[i]);
        if (i)pref1[i] = add(pref1[i], pref1[i - 1]);


        pref2[i] = mul(idx, pw2[i]);
        if (i)pref2[i] = add(pref2[i], pref2[i - 1]);
    }
}

pair<ll, ll> getHash(int l, int r) {

    ll ret1 = pref1[r];
    if (l)ret1 = add(ret1, -pref1[l - 1]);
    ret1 = mul(ret1, inv1[l]);


    ll ret2 = pref2[r];
    if (l)ret2 = add(ret2, -pref2[l - 1]);
    ret2 = mul(ret2, inv2[l]);
    return {ret1, ret2};
}

pair<ll, ll> getHash(string &str) {
    ll hashValue = 0, hashValue2 = 0;
    for (int i = 0; i < str.size(); i++) {
        int idx = str[i] - 'a' + 1;
        hashValue = add(hashValue, mul(idx, pw1[i]));
        hashValue2 = add(hashValue2, mul(idx, pw2[i]));
    }
    return {hashValue, hashValue2};
}


map<pll, ll> cnt;
vector<int> d;
string s;
ll dp[N];

void testCase() {
    ::memset(dp, 0, sizeof dp);
    pre();
    int n;
    cin >> n;
    map<int, int> sz;
    for (int i = 0; i < n; ++i) {
        string x;
        cin >> x;
        cnt[getHash(x)]++;
        if (sz[x.size()] == 0)sz[x.size()] = 1, d.push_back(x.size());
    }
    std::sort(d.begin(), d.end());
    cin >> s;
    generateHash(s);
    dp[s.size()] = 1;

    for (int ind = s.size() - 1; ind >= 0; ind--) {
        ll &ans = dp[ind];
        ans = 0;
        for (int i: d) {
            ll x = cnt.count(getHash(ind, ind + i - 1));
            if (ind + i <= s.size() and x)
                ans = add(ans, mul(x, dp[ind + i]));
        }
    }


    cout << dp[0];


}

int main() {
    //    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);

    flash;
    int T = 1;
//    cin >> T;
    while (T--) {
        testCase();
//        cout << el;
//        cout << endl;
    }

}
Editor is loading...
Leave a Comment