Untitled
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