Untitled
unknown
plain_text
a year ago
3.4 kB
8
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