Problem:
Separate String
You are given a string $t$ and a set $S$ of $N$ different strings. You need to separate $t$ such that each part is included in $S$.
For example, the following 4 separation methods satisfy the condition when $t = abab$ and $S = \{a, ab, b\}$.
$a,b,a,b$
$a,b,ab$
$ab,a,b$
$ab,ab$
Your task is to count the number of ways to separate $t$. Because the result can be large, you should output the remainder divided by $1,000,000,007$.
Input
The input consists of a single test case formatted as follows.
$N$
$s_1$
:
$s_N$
$t$
The first line consists of an integer $N$ ($1 \leq N \leq 100,000$) which is the number of the elements of $S$. The following $N$ lines consist of $N$ distinct strings separated by line breaks. The $i$-th string $s_i$ represents the $i$-th element of $S$. $s_i$ consists of lowercase letters and the length is between $1$ and $100,000$, inclusive. The summation of length of $s_i$ ($1 \leq i \leq N$) is at most $200,000$. The next line consists of a string $t$ which consists of lowercase letters and represents the string to be separated and the length is between $1$ and $100,000$, inclusive.
Output
Calculate the number of ways to separate $t$ and print the remainder divided by $1,000,000,007$.
Sample Input 1
3
a
b
ab
abab
Output for Sample Input 1
4
Sample Input 2
3
a
b
c
xyz
Output for Sample Input 2
0
Sample Input 3
7
abc
ab
bc
a
b
c
aa
aaabcbccababbc
Output for Sample Input 3
160
Sample Input 4
10
a
aa
aaa
aaaa
aaaaa
aaaaaa
aaaaaaa
aaaaaaaa
aaaaaaaaa
aaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Output for Sample Input 4
461695029

Submitted solutions:

code_snippet: # include <cstdio>
# include <iostream>
# include <cstring>
# include <string>
# define R register int
# define mod 1000000007

using namespace std;

const int maxn=200009;
int n,cnt=1;
char c[100005];
int ch[maxn][26],l;
bool vis[maxn];
int dp[100005];

inline void ins()
{
	int n,x=1,l=strlen(c+1);
	for (R i=1;i<=l;++i)
	{
		n=c[i]-'a';
		if(!ch[x][n]) ch[x][n]=++cnt;
		x=ch[x][n];
	}
	vis[x]=true;
}

inline void add (int x,int y)
{
	dp[x]=dp[x]+dp[y];
	if(dp[x]>=mod) dp[x]-=mod;
}

inline void Find (int pos)
{
	int x=1,n;
	for (int i=pos;i<=l;++i)
	{
        n=c[i]-'a';
        if(!ch[x][n]) break;
        x=ch[x][n];
        if(vis[x]) add(i,pos-1);
    }
}

int main()
{
	scanf("%d",&n);
	for (R i=1;i<=n;++i)
	{
		scanf("%s",c+1);
		ins();
	}
	dp[0]=1;
	scanf("%s",c+1);
	l=strlen(c+1);
	for (int i=0;i<l;++i)
		if(dp[i]) Find(i+1);
	printf("%d\n",dp[l]);
	return 0;
}
accuracy: 1
time_ms: 200
memory_kb: 24496
final_rank: 2

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct Node{
	int table[26];
	bool finish_FLG;
};

Node nodes[200001];

int node_index = 1,N,length;
ll dp[100001];
char buf[100001];

ll recursive(int start_pos){

	if(dp[start_pos] != -1)return dp[start_pos];

	stack<int> S;

	int tmp_ch,tmp_node_index = 0,ch_loc = start_pos,depth = 0;

	while(true){
		tmp_ch = buf[ch_loc]-'a';

		if(nodes[tmp_node_index].table[tmp_ch] == -1)break;

		tmp_node_index = nodes[tmp_node_index].table[tmp_ch];
		depth++;

		if(nodes[tmp_node_index].finish_FLG){
			S.push(start_pos+depth);
		}

		ch_loc++;

		if(buf[ch_loc] == '\0')break;
	}

	dp[start_pos] = 0;

	while(!S.empty()){
		dp[start_pos] += recursive(S.top());
		dp[start_pos] %= MOD;
		S.pop();
	}

	dp[start_pos] %= MOD;

	return dp[start_pos];
}

int main(){

	for(int i = 0; i <= 200000; i++){
		for(int k = 0; k < 26; k++)nodes[i].table[k] = -1;
		nodes[i].finish_FLG = false;
	}

	scanf("%d",&N);

	int tmp_ch,tmp_node_index,ch_loc;

	for(int loop = 0; loop < N; loop++){
		scanf("%s",buf);

		tmp_node_index = 0;
		ch_loc = 0;

		while(true){
			tmp_ch = buf[ch_loc]-'a';

			if(nodes[tmp_node_index].table[tmp_ch] == -1){
				nodes[tmp_node_index].table[tmp_ch] = node_index;
				tmp_node_index = node_index;
				node_index++;
			}else{
				tmp_node_index = nodes[tmp_node_index].table[tmp_ch];
			}
			ch_loc++;
			if(buf[ch_loc] == '\0'){
				nodes[tmp_node_index].finish_FLG = true;
				break;
			}
		}
	}

	scanf("%s",buf);

	for(length = 0; buf[length] != '\0'; length++);
	for(int i = 0; i < length; i++)dp[i] = -1;
	dp[length] = 1;

	printf("%lld\n",recursive(0));

	return 0;
}
accuracy: 1
time_ms: 340
memory_kb: 50972
final_rank: 4

code_snippet: #pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define vl vector<ll>
#define rep(i, n) for (ll i = 0; i < n; ++i)
constexpr ll MOD107 = 1000000007;

template <typename T>
struct RollingHash {
private:
    vector<int64_t> pow_bases;
    vector<int64_t> hashes;

    const int64_t MASK30 = (1ULL << 30) - 1;
    const int64_t MASK31 = (1ULL << 31) - 1;

    const int64_t MASK61 = mod;


    int64_t calc_mod(int64_t x){
        int64_t xu = x >> 61;
        int64_t xd = x & MASK61;
        int64_t res = xu + xd;
        if(res >= mod) res -= mod;
        return res;
    }

    int64_t mul(int64_t a, int64_t b){
        int64_t au = a >> 31;
        int64_t ad = a & MASK31;
        int64_t bu = b >> 31;
        int64_t bd = b & MASK31;
        int64_t mid = ad * bu + au * bd;
        int64_t midu = mid >> 30;
        int64_t midd = mid & MASK30;
        return calc_mod(au * bu * 2 + midu + (midd << 31) + ad * bd);
    }

public:
    const int64_t base;
    static const int64_t mod = (1LL << 61) - 1;

    static int64_t generate_base() {
        mt19937_64 rnd(chrono::steady_clock::now().time_since_epoch().count());
        return uniform_int_distribution<int64_t>(1, mod - 1)(rnd);
    }

    RollingHash(int64_t base) : base(base) {
        pow_bases.push_back(1);
        hashes.push_back(0);
    }
    template <typename Iterable>
    RollingHash(Iterable s, int64_t base) : RollingHash(base) {
        pow_bases.reserve(s.size() + 1);
        hashes.reserve(s.size() + 1);
        for (int i = 0; i < static_cast<int>(s.size()); ++i) {
            push_back(s[i]);
        }
    }

    void push_back(T c) {
        hashes.push_back(calc_mod(mul(hashes.back(), base) + (int64_t)c));
        if (pow_bases.size() < hashes.size()) pow_bases.push_back(mul(pow_bases.back(), base));
    }

    int64_t get(int l, int r) {
        int64_t hash = calc_mod(hashes[r] - calc_mod(mul(hashes[l], pow_bases[r - l])));
        return hash;
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    ll n; cin >> n;
    unordered_set<ll> hashes;
    set<ll> sizes_set;
    ll base = RollingHash<char>::generate_base();
    rep(i, n) {
        string s; cin >> s;
        RollingHash<char> rh(s, base);
        hashes.insert(rh.get(0, s.size()));
        sizes_set.insert(s.size());
    }
    vector<ll> sizes;
    for (ll size : sizes_set) {
        sizes.push_back(size);
    }

    string t; cin >> t;
    RollingHash<char> trh(t, base);
    vector<ll> dp(t.size() + 1, 0);
    dp[0] = 1;
    rep(i, t.size()) {
        for (ll& len : sizes) {
            if (t.size() < i + len) break;
            if (hashes.count(trh.get(i, i + len))) {
                dp[i + len] += dp[i];
                dp[i + len] %= MOD107;
            }
        }
    }

    cout << dp[t.size()] << endl;
}
accuracy: 1
time_ms: 1320
memory_kb: 6676
final_rank: 15

code_snippet: #include <algorithm>
#include <cassert>
#include <numeric>
#include <type_traits>
#ifdef _MSC_VER
#include <intrin.h>
#endif
#include <utility>
#ifdef _MSC_VER
#include <intrin.h>
#endif
namespace atcoder {
namespace internal {
constexpr long long safe_mod(long long x, long long m) {
  x %= m;
  if (x < 0) x += m;
  return x;
}
struct barrett {
  unsigned int _m;
  unsigned long long im;
  explicit barrett(unsigned int m)
      : _m(m), im((unsigned long long)(-1) / m + 1) {}
  unsigned int umod() const { return _m; }
  unsigned int mul(unsigned int a, unsigned int b) const {
    unsigned long long z = a;
    z *= b;
#ifdef _MSC_VER
    unsigned long long x;
    _umul128(z, im, &x);
#else
    unsigned long long x =
        (unsigned long long)(((unsigned __int128)(z)*im) >> 64);
#endif
    unsigned int v = (unsigned int)(z - x * _m);
    if (_m <= v) v += _m;
    return v;
  }
};
constexpr long long pow_mod_constexpr(long long x, long long n, int m) {
  if (m == 1) return 0;
  unsigned int _m = (unsigned int)(m);
  unsigned long long r = 1;
  unsigned long long y = safe_mod(x, m);
  while (n) {
    if (n & 1) r = (r * y) % _m;
    y = (y * y) % _m;
    n >>= 1;
  }
  return r;
}
constexpr bool is_prime_constexpr(int n) {
  if (n <= 1) return false;
  if (n == 2 || n == 7 || n == 61) return true;
  if (n % 2 == 0) return false;
  long long d = n - 1;
  while (d % 2 == 0) d /= 2;
  constexpr long long bases[3] = {2, 7, 61};
  for (long long a : bases) {
    long long t = d;
    long long y = pow_mod_constexpr(a, t, n);
    while (t != n - 1 && y != 1 && y != n - 1) {
      y = y * y % n;
      t <<= 1;
    }
    if (y != n - 1 && t % 2 == 0) return false;
  }
  return true;
}
template <int n>
constexpr bool is_prime = is_prime_constexpr(n);
constexpr std::pair<long long, long long> inv_gcd(long long a, long long b) {
  a = safe_mod(a, b);
  if (a == 0) return {b, 0};
  long long s = b, t = a;
  long long m0 = 0, m1 = 1;
  while (t) {
    long long u = s / t;
    s -= t * u;
    m0 -= m1 * u;  // |m1 * u| <= |m1| * s <= b
    auto tmp = s;
    s = t;
    t = tmp;
    tmp = m0;
    m0 = m1;
    m1 = tmp;
  }
  if (m0 < 0) m0 += b / s;
  return {s, m0};
}
constexpr int primitive_root_constexpr(int m) {
  if (m == 2) return 1;
  if (m == 167772161) return 3;
  if (m == 469762049) return 3;
  if (m == 754974721) return 11;
  if (m == 998244353) return 3;
  int divs[20] = {};
  divs[0] = 2;
  int cnt = 1;
  int x = (m - 1) / 2;
  while (x % 2 == 0) x /= 2;
  for (int i = 3; (long long)(i)*i <= x; i += 2)
    if (x % i == 0) {
      divs[cnt++] = i;
      while (x % i == 0) x /= i;
    }
  if (x > 1) divs[cnt++] = x;
  for (int g = 2;; g++) {
    bool ok = true;
    for (int i = 0; i < cnt; i++)
      if (pow_mod_constexpr(g, (m - 1) / divs[i], m) == 1) {
        ok = false;
        break;
      }
    if (ok) return g;
  }
}
template <int m>
constexpr int primitive_root = primitive_root_constexpr(m);
unsigned long long floor_sum_unsigned(unsigned long long n,
                                      unsigned long long m,
                                      unsigned long long a,
                                      unsigned long long b) {
  unsigned long long ans = 0;
  while (true) {
    if (a >= m) {
      ans += n * (n - 1) / 2 * (a / m);
      a %= m;
    }
    if (b >= m) {
      ans += n * (b / m);
      b %= m;
    }
    unsigned long long y_max = a * n + b;
    if (y_max < m) break;
    n = (unsigned long long)(y_max / m);
    b = (unsigned long long)(y_max % m);
    std::swap(m, a);
  }
  return ans;
}
}  // namespace internal
}  // namespace atcoder
#include <cassert>
#include <numeric>
#include <type_traits>
namespace atcoder {
namespace internal {
#ifndef _MSC_VER
template <class T>
using is_signed_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value ||
                                  std::is_same<T, __int128>::value,
                              std::true_type, std::false_type>::type;
template <class T>
using is_unsigned_int128 =
    typename std::conditional<std::is_same<T, __uint128_t>::value ||
                                  std::is_same<T, unsigned __int128>::value,
                              std::true_type, std::false_type>::type;
template <class T>
using make_unsigned_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value, __uint128_t,
                              unsigned __int128>;
template <class T>
using is_integral =
    typename std::conditional<std::is_integral<T>::value ||
                                  is_signed_int128<T>::value ||
                                  is_unsigned_int128<T>::value,
                              std::true_type, std::false_type>::type;
template <class T>
using is_signed_int =
    typename std::conditional<(is_integral<T>::value &&
                               std::is_signed<T>::value) ||
                                  is_signed_int128<T>::value,
                              std::true_type, std::false_type>::type;
template <class T>
using is_unsigned_int =
    typename std::conditional<(is_integral<T>::value &&
                               std::is_unsigned<T>::value) ||
                                  is_unsigned_int128<T>::value,
                              std::true_type, std::false_type>::type;
template <class T>
using to_unsigned = typename std::conditional<
    is_signed_int128<T>::value, make_unsigned_int128<T>,
    typename std::conditional<std::is_signed<T>::value, std::make_unsigned<T>,
                              std::common_type<T>>::type>::type;
#else
template <class T>
using is_integral = typename std::is_integral<T>;
template <class T>
using is_signed_int =
    typename std::conditional<is_integral<T>::value && std::is_signed<T>::value,
                              std::true_type, std::false_type>::type;
template <class T>
using is_unsigned_int =
    typename std::conditional<is_integral<T>::value &&
                                  std::is_unsigned<T>::value,
                              std::true_type, std::false_type>::type;
template <class T>
using to_unsigned =
    typename std::conditional<is_signed_int<T>::value, std::make_unsigned<T>,
                              std::common_type<T>>::type;
#endif
template <class T>
using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;
template <class T>
using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;
template <class T>
using to_unsigned_t = typename to_unsigned<T>::type;
}  // namespace internal
}  // namespace atcoder
namespace atcoder {
namespace internal {
struct modint_base {};
struct static_modint_base : modint_base {};
template <class T>
using is_modint = std::is_base_of<modint_base, T>;
template <class T>
using is_modint_t = std::enable_if_t<is_modint<T>::value>;
}  // namespace internal
template <int m, std::enable_if_t<(1 <= m)> * = nullptr>
struct static_modint : internal::static_modint_base {
  using mint = static_modint;

 public:
  static constexpr int mod() { return m; }
  static mint raw(int v) {
    mint x;
    x._v = v;
    return x;
  }
  static_modint() : _v(0) {}
  template <class T, internal::is_signed_int_t<T> * = nullptr>
  static_modint(T v) {
    long long x = (long long)(v % (long long)(umod()));
    if (x < 0) x += umod();
    _v = (unsigned int)(x);
  }
  template <class T, internal::is_unsigned_int_t<T> * = nullptr>
  static_modint(T v) {
    _v = (unsigned int)(v % umod());
  }
  unsigned int val() const { return _v; }
  mint &operator++() {
    _v++;
    if (_v == umod()) _v = 0;
    return *this;
  }
  mint &operator--() {
    if (_v == 0) _v = umod();
    _v--;
    return *this;
  }
  mint operator++(int) {
    mint result = *this;
    ++*this;
    return result;
  }
  mint operator--(int) {
    mint result = *this;
    --*this;
    return result;
  }
  mint &operator+=(const mint &rhs) {
    _v += rhs._v;
    if (_v >= umod()) _v -= umod();
    return *this;
  }
  mint &operator-=(const mint &rhs) {
    _v -= rhs._v;
    if (_v >= umod()) _v += umod();
    return *this;
  }
  mint &operator*=(const mint &rhs) {
    unsigned long long z = _v;
    z *= rhs._v;
    _v = (unsigned int)(z % umod());
    return *this;
  }
  mint &operator/=(const mint &rhs) { return *this = *this * rhs.inv(); }
  mint operator+() const { return *this; }
  mint operator-() const { return mint() - *this; }
  mint pow(long long n) const {
    assert(0 <= n);
    mint x = *this, r = 1;
    while (n) {
      if (n & 1) r *= x;
      x *= x;
      n >>= 1;
    }
    return r;
  }
  mint inv() const {
    if (prime) {
      assert(_v);
      return pow(umod() - 2);
    } else {
      auto eg = internal::inv_gcd(_v, m);
      assert(eg.first == 1);
      return eg.second;
    }
  }
  friend mint operator+(const mint &lhs, const mint &rhs) {
    return mint(lhs) += rhs;
  }
  friend mint operator-(const mint &lhs, const mint &rhs) {
    return mint(lhs) -= rhs;
  }
  friend mint operator*(const mint &lhs, const mint &rhs) {
    return mint(lhs) *= rhs;
  }
  friend mint operator/(const mint &lhs, const mint &rhs) {
    return mint(lhs) /= rhs;
  }
  friend bool operator==(const mint &lhs, const mint &rhs) {
    return lhs._v == rhs._v;
  }
  friend bool operator!=(const mint &lhs, const mint &rhs) {
    return lhs._v != rhs._v;
  }

 private:
  unsigned int _v;
  static constexpr unsigned int umod() { return m; }
  static constexpr bool prime = internal::is_prime<m>;
};
template <int id>
struct dynamic_modint : internal::modint_base {
  using mint = dynamic_modint;

 public:
  static int mod() { return (int)(bt.umod()); }
  static void set_mod(int m) {
    assert(1 <= m);
    bt = internal::barrett(m);
  }
  static mint raw(int v) {
    mint x;
    x._v = v;
    return x;
  }
  dynamic_modint() : _v(0) {}
  template <class T, internal::is_signed_int_t<T> * = nullptr>
  dynamic_modint(T v) {
    long long x = (long long)(v % (long long)(mod()));
    if (x < 0) x += mod();
    _v = (unsigned int)(x);
  }
  template <class T, internal::is_unsigned_int_t<T> * = nullptr>
  dynamic_modint(T v) {
    _v = (unsigned int)(v % mod());
  }
  unsigned int val() const { return _v; }
  mint &operator++() {
    _v++;
    if (_v == umod()) _v = 0;
    return *this;
  }
  mint &operator--() {
    if (_v == 0) _v = umod();
    _v--;
    return *this;
  }
  mint operator++(int) {
    mint result = *this;
    ++*this;
    return result;
  }
  mint operator--(int) {
    mint result = *this;
    --*this;
    return result;
  }
  mint &operator+=(const mint &rhs) {
    _v += rhs._v;
    if (_v >= umod()) _v -= umod();
    return *this;
  }
  mint &operator-=(const mint &rhs) {
    _v += mod() - rhs._v;
    if (_v >= umod()) _v -= umod();
    return *this;
  }
  mint &operator*=(const mint &rhs) {
    _v = bt.mul(_v, rhs._v);
    return *this;
  }
  mint &operator/=(const mint &rhs) { return *this = *this * rhs.inv(); }
  mint operator+() const { return *this; }
  mint operator-() const { return mint() - *this; }
  mint pow(long long n) const {
    assert(0 <= n);
    mint x = *this, r = 1;
    while (n) {
      if (n & 1) r *= x;
      x *= x;
      n >>= 1;
    }
    return r;
  }
  mint inv() const {
    auto eg = internal::inv_gcd(_v, mod());
    assert(eg.first == 1);
    return eg.second;
  }
  friend mint operator+(const mint &lhs, const mint &rhs) {
    return mint(lhs) += rhs;
  }
  friend mint operator-(const mint &lhs, const mint &rhs) {
    return mint(lhs) -= rhs;
  }
  friend mint operator*(const mint &lhs, const mint &rhs) {
    return mint(lhs) *= rhs;
  }
  friend mint operator/(const mint &lhs, const mint &rhs) {
    return mint(lhs) /= rhs;
  }
  friend bool operator==(const mint &lhs, const mint &rhs) {
    return lhs._v == rhs._v;
  }
  friend bool operator!=(const mint &lhs, const mint &rhs) {
    return lhs._v != rhs._v;
  }

 private:
  unsigned int _v;
  static internal::barrett bt;
  static unsigned int umod() { return bt.umod(); }
};
template <int id>
internal::barrett dynamic_modint<id>::bt(998244353);
using modint998244353 = static_modint<998244353>;
using modint1000000007 = static_modint<1000000007>;
using modint = dynamic_modint<-1>;
namespace internal {
template <class T>
using is_static_modint = std::is_base_of<internal::static_modint_base, T>;
template <class T>
using is_static_modint_t = std::enable_if_t<is_static_modint<T>::value>;
template <class>
struct is_dynamic_modint : public std::false_type {};
template <int id>
struct is_dynamic_modint<dynamic_modint<id>> : public std::true_type {};
template <class T>
using is_dynamic_modint_t = std::enable_if_t<is_dynamic_modint<T>::value>;
}  // namespace internal
}  // namespace atcoder
#include <cstring>
#include <ext/pb_ds/assoc_container.hpp>
#include <iostream>
#include <vector>
using mint = atcoder::modint1000000007;
const mint kBs(100003);
template <typename T1, typename T2>
void checkmax(T1 &x, T2 y) {
  if (x < y) x = y;
}
template <typename T1, typename T2>
void checkmin(T1 &x, T2 y) {
  if (x > y) x = y;
}
int n;
mint pw[100001], a[100001], f[100001];
char s[100005], t[100005];
__gnu_pbds::gp_hash_table<int, bool> mp[100001];
int main(int argc, char const *argv[]) {
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(nullptr), std::cout.tie(nullptr);
  std::cin >> n;
  std::vector<int> l(n);
  for (int i = 0; i < n; i++) {
    std::cin >> (s + 1), l[i] = std::strlen(s + 1);
    mint h;
    for (int j = 1; j <= l[i]; j++) h = h * kBs + s[j];
    mp[l[i]][h.val()] = true;
  }
  std::sort(l.begin(), l.end());
  l.erase(std::unique(l.begin(), l.end()), l.end());
  std::cin >> (t + 1);
  int m = std::strlen(t + 1);
  pw[0] = mint::raw(1);
  for (int i = 1; i <= m; i++) pw[i] = pw[i - 1] * kBs;
  for (int i = 1; i <= m; i++) a[i] = a[i - 1] * kBs + t[i];
  auto calc = [](int l, int r) { return a[r] - a[l - 1] * pw[r - l + 1]; };
  f[0] = mint::raw(1);
  for (int i = 1; i <= m; i++)
    for (const auto j : l) {
      if (j > i) break;
      if (mp[j][calc(i - j + 1, i).val()]) f[i] += f[i - j];
    }
  std::cout << f[m].val() << '\n';
  return 0;
}
accuracy: 1
time_ms: 420
memory_kb: 211528
final_rank: 14

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); i++)
using namespace std;
typedef long long ll;
#include <bits/stdc++.h>
using namespace std;

template< int mod >
struct Fp {
    int x;
    Fp() : x(0) {}
    Fp(int64_t y) : x(y >= 0 ? y % mod : (mod + y % mod) % mod) {}
    Fp &operator+=(const Fp &p) { if((x += p.x) >= mod) x -= mod; return *this; }
    Fp &operator-=(const Fp &p) { if((x += mod - p.x) >= mod) x -= mod; return *this; }
    Fp &operator*=(const Fp &p) { x = (int)(1LL * x * p.x % mod); return *this; }
    Fp &operator/=(const Fp &p) { *this *= p.inv(); return *this; }
    Fp operator-() const { return Fp(-x); }
    Fp operator+(const Fp &p) const { return Fp(*this) += p; }
    Fp operator-(const Fp &p) const { return Fp(*this) -= p; }
    Fp operator*(const Fp &p) const { return Fp(*this) *= p; }
    Fp operator/(const Fp &p) const { return Fp(*this) /= p; }
    bool operator==(const Fp &p) const { return x == p.x; }
    bool operator!=(const Fp &p) const { return x != p.x; }

    Fp inv() const {
        int a = x, b = mod, u = 1, v = 0, t;
        while(b > 0) {
            t = a / b;
            swap(a -= t * b, b);
            swap(u -= t * v, v);
        }
        return Fp(u);
    }

    Fp pow(int64_t n) const {
        Fp ret(1), mul(x);
        while(n > 0) {
            if(n & 1) ret *= mul;
            mul *= mul;
            n >>= 1;
        }
        return ret;
    }

    friend ostream &operator<<(ostream &os, const Fp &p) { return os << p.x; }
    friend istream &operator>>(istream &is, Fp &a) {
        int64_t t;
        is >> t;
        a = Fp< mod > (t);
        return (is);
    }

    static int get_mod() { return mod; }
};

using mint = Fp<1000000007>;

constexpr int M = 2;
constexpr ll MODS[M] = {ll(1e9+7), ll(1e9+9)};

struct RollingHash{
    std::vector<std::vector<ll> > powb, rhash;
    int N;
    void build(const std::string& str, const ll base = ll(1e5 + 7)) {
        N = str.size();
        powb.resize(M);
        rhash.resize(M);
        for(int k=0;k<M;k++){
            powb[k].resize(N + 1);
            rhash[k].resize(N + 1);
            powb[k][0] = 1;
            rhash[k][0] = 0;
            for (int i=0; i<N; i++) {
                rhash[k][i+1] = (rhash[k][i] * base + str[i]) % MODS[k];
                powb[k][i+1] = powb[k][i] * base % MODS[k];
            }
        }
    }

    //[l,r)
    ll get_hash(int k, int l, int r) { return (rhash[k][r] - rhash[k][l]*powb[k][r-l]%MODS[k]+MODS[k])%MODS[k]; }

    bool match(int l1, int r1, int l2, int r2){
        bool res = true;
        for(int k=0; k<M; k++){
            res &= get_hash(k, l1, r1) == get_hash(k, l2, r2);
        }
        return res;
    }
};

bool match(RollingHash& lhs, RollingHash& rhs, int l1, int r1, int l2, int r2){
    int res = true;
    rep(k,M){
        res &= lhs.get_hash(k,l1,r1) == rhs.get_hash(k,l2,r2);
    }
    return res;
}

template <int char_size, int margin>
struct Trie{
    struct TrieNode{
        int nxt[char_size];  //子ノードの番号
        vector<int> idx;  // prefixの一致する文字列の番号の集合
        bool exist = false;
        TrieNode(){
            fill(nxt, nxt+char_size, -1);
        }
    };

    vector<TrieNode> nodes;
    Trie(){
        nodes.push_back(TrieNode());
    };
    void add(const string &str, int id){
        int node_index = 0;
        nodes[0].idx.push_back(id);
        for(int i=0;i<int(str.size());i++){
            int c = str[i] - margin;
            if(nodes[node_index].nxt[c] == -1){
                nodes[node_index].nxt[c] = int(nodes.size());
                nodes.push_back(TrieNode());
            }
            node_index = nodes[node_index].nxt[c];
            nodes[node_index].idx.push_back(id);
        }
        nodes[node_index].exist = true;
    }
    // 文字列の追加
    void add(const string &str){
        add(str, int(nodes[0].idx.size()));
    }
    // 対応するnode番号の検索
    int find(const string &str){
        int node_index = 0;
        for(int i=0;i<int(str.size());i++){
            int c = str[i] - margin;
            if(nodes[node_index].nxt[c] == -1){
                return -1;
            }
            node_index = nodes[node_index].nxt[c];
        }
        return node_index;
    }
    int next_node(const int index, const char c){
        int j = c - margin;
        return nodes[index].nxt[j];
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(0);
    
    int n; cin >> n;
    int sum = 0;
    vector<string> s(n);
    rep(i,n) {
        cin >> s[i];
        sum += s[i].size();
    }

    string t; cin >> t;
    Trie<26,'a'> trie;
    vector<RollingHash> hashs;
    RollingHash t_rh; t_rh.build(t);
    int SQRT = sqrt(sum) + 1;

    rep(i,n){
        if(s[i].size() < SQRT){
            trie.add(s[i]);
        }else{
            hashs.push_back(RollingHash());
            hashs.back().build(s[i]);
        }
    }
    
    vector<mint> dp(t.size() + 1);
    dp[0] = 1;
    rep(i,t.size()){
        if(dp[i] == 0) continue;

        // |s| < sqrt(sum(|s|))
        int id = 0, j = 0;
        while(i + j < t.size()){
            id = trie.next_node(id, t[i + j]);
            if(id == -1) break;
            if(trie.nodes[id].exist) dp[i + j + 1] += dp[i];
            j++;
        }

        // |s| < sqrt(sum(|s|))
        for(auto &rh : hashs){
            if(i + rh.N > t.size()) continue;
            if(match(t_rh, rh, i, i + rh.N, 0, rh.N)) dp[i + rh.N] += dp[i];
        }
    }
    cout << dp[t.size()] << endl;
}
accuracy: 1
time_ms: 1330
memory_kb: 48144
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define Maxn 200007
#define modp1 998244353
#define modp2 100000007
#define modp 1000000007
int n,m;
char s[Maxn];
int len[Maxn];
int h[Maxn][2],ha[Maxn][2];
unordered_map<long long,bool> mp;
int f[Maxn];
int que[Maxn];
int bin[Maxn][2];
int calc1(int lx,int rx)
{
	return (ha[rx][0]-(1LL*ha[lx-1][0]*bin[rx-lx+1][0])%modp1+modp1)%modp1;
}
int calc2(int lx,int rx)
{
	return (ha[rx][1]-(1LL*ha[lx-1][1]*bin[rx-lx+1][1])%modp2+modp2)%modp2;
}
long long calc(int a,int b)
{
	return 1LL*a*modp2+b;
}
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	{
		scanf("%s",s+1);
		len[i]=strlen(s+1);
		for (int j=1;j<=len[i];j++)
		{
			h[i][0]=(27LL*h[i][0]+s[j]-'a'+1)%modp1;
			h[i][1]=(27LL*h[i][1]+s[j]-'a'+1)%modp2;
		}
	}
	bin[0][0]=1,bin[0][1]=1;
	for (int i=1;i<=200000;i++)
	{
		bin[i][0]=(27LL*bin[i-1][0])%modp1;
		bin[i][1]=(27LL*bin[i-1][1])%modp2;
	}
	scanf("%s",s+1);
	m=strlen(s+1);
	for (int i=1;i<=m;i++)
	{
		ha[i][0]=(27LL*ha[i-1][0]+s[i]-'a'+1)%modp1;
		ha[i][1]=(27LL*ha[i-1][1]+s[i]-'a'+1)%modp2;
	}
	for (int i=1;i<=n;i++)
	{
		que[i]=len[i];
		mp[calc(h[i][0],h[i][1])]=true;
	}
	sort(que+1,que+n+1);
	int cnt=1;
	for (int i=2;i<=n;i++)
		if (que[i]!=que[cnt]) que[++cnt]=que[i];
	f[0]=1;
	for (int i=1;i<=m;i++)
	{
		for (int j=1;j<=cnt&&que[j]<=i;j++)
			if (mp.count(calc(calc1(i-que[j]+1,i),calc2(i-que[j]+1,i)))) f[i]=(f[i]+f[i-que[j]])%modp;
	}
	printf("%d\n",(f[m]+modp)%modp);
	return 0;
}
accuracy: 1
time_ms: 1220
memory_kb: 10124
final_rank: 11

code_snippet: #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<unordered_set>
using namespace std;
const int N = 200005,se = 29 ,mod = 998244353,md=1000000007;
int n,hsh[N],mi[N],mi2[N],hh[N],m,dp[N],zy[N];
char s[N];
unordered_set<int> st,st2;
inline int plu(int x,int y) { x+=y; if (x>=md) x-=md; return x; }
inline int pl(int x,int y) { x+=y; if (x>=mod) x-=mod; return x; }
inline int hs1(int l,int r)
{
	return pl(hsh[r]-1ll*hsh[l-1]*mi[r-l+1]%mod,mod);
}
inline int hs2(int l,int r)
{
	return plu(hh[r]-1ll*hh[l-1]*mi2[r-l+1]%md,md);
}
int main()
{
	//freopen("a.in","r",stdin);
	mi[0]=mi2[0]=1;
	for (int i=1;i<=200000;i++)
	 mi[i]=1ll*mi[i-1]*se%mod,
	 mi2[i]=1ll*mi2[i-1]*se%md;
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	{
		int tp=0,tp2=0; scanf("%s",s+1); m=strlen(s+1);
		zy[++zy[0]]=m;
		for (int j=1;j<=m;j++)
		 tp=pl(1ll*tp*se%mod,s[j]-'a'+1),
		 tp2=plu(1ll*tp2*se%md,s[j]-'a'+1);
		st.insert(tp); st2.insert(tp2);
		//cout<<tp<<" "<<tp2<<endl;
	}
	sort(zy+1,zy+n+1); int tp=1;
	for (int i=2;i<=n;i++) if (zy[i]!=zy[tp]) zy[++tp]=zy[i];
	scanf("%s",s+1); m=strlen(s+1);
	for (int i=1;i<=m;i++)
	 hsh[i]=pl(1ll*hsh[i-1]*se%mod,s[i]-'a'+1),
	 hh[i]=plu(1ll*hh[i-1]*se%md,s[i]-'a'+1);
	dp[0]=1;
	for (int i=1;i<=m;i++)
	{
		for (int j=1;j<=tp&&i-zy[j]>=0;j++)
		{
			//cout<<zy[j]<<" "<<i<<" "<<hs1(i-zy[j]+1,i)<<" "<<hs2(i-zy[j]+1,i)<<endl;
			if ((st.find(hs1(i-zy[j]+1,i))!=st.end())
			&& (st2.find(hs2(i-zy[j]+1,i))!=st2.end()))
			 dp[i]=plu(dp[i],dp[i-zy[j]]);
		}
	}
	printf("%d\n",dp[m]);
	return 0;
}
accuracy: 1
time_ms: 1250
memory_kb: 8176
final_rank: 13

code_snippet: #include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
const unsigned long long w=100007,p=1000000007;
const int bl=150;
unsigned long long hsh[200003],poww[200003];
inline unsigned long long get(int l,int r){
	return (hsh[r]-hsh[l-1]*poww[r-l+1]%p+p)%p;;
}
int n,m;
char s[200003];
std::string a[200003];
unsigned long long hs[200003];
std::vector<int> pre[200003];
std::unordered_map<unsigned long long,int> M;
std::vector<int> list[200003];
long long f[200003];
int main(){
	scanf("%d",&m);
	for (int i=1;i<=m;i++) {
		std::cin>>a[i];
		for (int j=0;j<a[i].length();j++) hs[i]=(hs[i]*w+a[i][j])%p;
	}
	scanf("%s",s+1);
	n=strlen(s+1);
	poww[0]=1;for (int i=1;i<=200001;i++) poww[i]=poww[i-1]*w%p;
	for (int i=1;i<=n;i++) hsh[i]=(hsh[i-1]*w+s[i])%p;
	for (int i=1;i<=m;i++) if (a[i].length()>bl){
		for (int j=1;j+a[i].length()-1<=n;j++) if (hs[i]==get(j,j+a[i].length()-1)){
			pre[j+a[i].length()-1].push_back(j-1);
		}
	}
	int tot=0;
	for (int l=1;l<=bl;l++){
		M.clear();tot=0;
		for (int i=1;i+l-1<=n;i++) {
			unsigned long long tmp=get(i,i+l-1);
			if (M.find(tmp)==M.end()){
				M[tmp]=++tot;
				list[tot].clear();
				list[tot].push_back(i);
			}else{
				list[M[tmp]].push_back(i);
			}
		}
		for (int i=1;i<=m;i++) if (a[i].length()==l){
			if (M.find(hs[i])!=M.end()){
				int p=M[hs[i]];
				for (int j=0;j<list[p].size();j++) pre[list[p][j]+l-1].push_back(list[p][j]-1);
			}
		}
	}
	f[0]=1;
	for (int i=1;i<=n;i++){
		//printf(":%d :",i);for (int j=0;j<pre[i].size();j++) printf("%d ",pre[i][j]);printf("\n");
		for (int j=0;j<pre[i].size();j++) f[i]=f[i]+f[pre[i][j]];
		f[i]%=p;
	}
	printf("%lld\n",f[n]);
	return 0;
}
accuracy: 1
time_ms: 1170
memory_kb: 425120
final_rank: 19

code_snippet: #include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <unordered_set>

using namespace std;

typedef long long LL;

const int P0 = 23;
const int P1 = 67;
const int MOD0 = 998244353;
const int MOD1 = 1000000007;

typedef pair<int , int> P;

#define mkp(a , b) make_pair(a , b)
#define ft first
#define sd second

inline P operator + (P p , P q){return mkp((p.ft + q.ft) % MOD0 , (p.sd + q.sd) % MOD1);}
inline P operator - (P p , P q){return mkp((p.ft - q.ft + MOD0) % MOD0 , (p.sd - q.sd + MOD1) % MOD1);}
inline P operator * (P p , P q){return mkp(1ll * p.ft * q.ft % MOD0 ,  1ll * p.sd * q.sd % MOD1);}

inline P &operator +=(P &p , P q){return p = p + q;}
inline P &operator -=(P &p , P q){return p = p - q;}
inline P &operator *=(P &p , P q){return p = p * q;}

const int N = 100005;
const int L = 100005;

unordered_set<LL> exist;

P hash_value[L] , inv[L] , invp;
char s[L] , t[L];
int len[N];
int f[L];
int n , l;

inline int quick_power(int x , int y , int mod)
{
	int ret = 1;
	for (;y;y >>= 1 , x = 1ll * x * x % mod) if (y & 1) ret = 1ll * ret * x % mod;
	return ret;
}

inline void add(int &x , int y){x = x + y >= MOD1 ? x + y - MOD1 : x + y;}

int main()
{
	//freopen("b.in" , "r" , stdin) , freopen("b.out" , "w" , stdout);
	scanf("%d" , &n);
	for (int i = 1 , l_;i <= n;++ i)
	{
		scanf("%s" , s + 1) , l_ = strlen(s + 1) , len[i] = l_;
		P base = mkp(1 , 1) , cur = mkp(0 , 0);
		for (int j = 1;j <= l_;++ j)
		{
			cur += base * mkp(s[j] - 'a' + 1 , s[j] - 'a' + 1);
			base *= mkp(P0 , P1);
		}
		exist.insert(cur.ft * 1000000000ll + cur.sd);
	}
	sort(len + 1 , len + 1 + n) , n = unique(len + 1 , len + 1 + n) - (len + 1);
	scanf("%s" , t + 1) , l = strlen(t + 1);
	inv[0] = mkp(1 , 1) , invp = mkp(quick_power(P0 , MOD0 - 2 , MOD0) , quick_power(P1 , MOD1 - 2 , MOD1));
	P base = mkp(1 , 1);
	f[0] = 1;
	for (int i = 1;i <= l;++ i)
	{
		inv[i] = inv[i - 1] * invp;
		hash_value[i] = hash_value[i - 1] + base * mkp(t[i] - 'a' + 1 , t[i] - 'a' + 1);
		for (int j = 1;j <= n && len[j] <= i;++ j)
		{
			P range_hash = (hash_value[i] - hash_value[i - len[j]]) * inv[i - len[j]];
			if (exist.count(range_hash.ft * 1000000000ll + range_hash.sd)) add(f[i] , f[i - len[j]]);
		}
		base *= mkp(P0 , P1);
	}
	printf("%d\n" , f[l]);
	//fclose(stdin) , fclose(stdout);
	return 0;
}
accuracy: 1
time_ms: 1240
memory_kb: 6328
final_rank: 12

code_snippet: #include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cctype>
#include<queue>
#define ll long long
#define N (1000000 + 10)
#define Mod 1000000007ll
using namespace std;
ll n,id,son[N][26],Ed[N],fail[N],Step[N],f[N];
string st;
char S[N];

ll read() {
    char c=getchar();
    ll r=0,f=1;
    while (!isdigit(c)) {
        if (c=='-') f=-1;
        c=getchar();
    }
    while (isdigit(c)) {
        r=(r*10)+(c^48);
        c=getchar();
    }
    return r*f;
}

void Trie(string s) {
    ll len=s.length(),x=0;
    for (ll i=0;i<s.length();i++) {
        if (!son[x][s[i]-'a']) {
        	son[x][s[i]-'a']=++id;
        	Step[id]=Step[x]+1;
        }
        x=son[x][s[i]-'a'];
    }
    Ed[x]++;
}

queue<ll> q;

void Get_Fail() {
    for (ll i=0;i<26;i++) 
        if (son[0][i]) {
            fail[son[0][i]]=0;
            q.push(son[0][i]);
        }
    while (!q.empty()) {
        ll x=q.front();
        q.pop();
        for (ll i=0;i<26;i++) 
            if (son[x][i]) {
                fail[son[x][i]]=son[fail[x]][i];
                q.push(son[x][i]);
            }
            else son[x][i]=son[fail[x]][i];
    }
}

void Query() {
	f[0]=1;
    ll len=strlen(S+1),x=0;
    for (ll i=1;i<=len;i++) {
        x=son[x][S[i]-'a'];
        for (ll j=x;j;j=fail[j]) {
            if (Ed[j]) {
            	f[i]=(f[i]+f[i-Step[j]])%Mod;
            }
        }
    }
}

int main() {
    n=read();
    for (ll i=1;i<=n;i++) {
        cin>>st;
        Trie(st);
    }
    Get_Fail();
    cin>>(S+1);
    Query();
    ll ans=strlen(S+1);
    printf("%lld\n",f[ans]%Mod);
}
accuracy: 1
time_ms: 1020
memory_kb: 57688
final_rank: 10

code_snippet: ///〆〆〆〆〆
#include<set>
#include<map>
#include<cstdio>
#include<iostream> 
#include<cstring>
#include<cmath>
#include<cctype>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define interesting int
const int N=4E5+10,mod=1E9+7;
int n,sum=0;
int q[N],f[N],L[N];
char s[N];
struct AC_auto{
    int s,fail,dep;
    int son[26];
}p[N];
void build(int x){
    int t=0,len=strlen(s);
    for(int i=0;i<len;i++){
        if(!p[t].son[s[i]-'a']){
			p[t].son[s[i]-'a']=++sum;
			p[sum].dep=p[t].dep+1;
		}
        t=p[t].son[s[i]-'a'];
    }
    p[t].s++;
}
void get_fail(void){
	int h=0,w=1;
    p[0].fail=0;
    for(int i=0;i<26;i++) if(p[0].son[i]){
        p[p[0].son[i]].fail=0;
        q[++h]=p[0].son[i];
	}
    while(h>=w){
        int u=q[w++];
        for(int i=0;i<26;i++) if(p[u].son[i]){
            p[p[u].son[i]].fail=p[p[u].fail].son[i];
            q[++h]=p[u].son[i];
        }
        else p[u].son[i]=p[p[u].fail].son[i];
    }
}
inline void add(int&x,int y){(x+=y)>=mod?x-=mod:0;}
inline int Nxt(int x){
	if(!x)return 0;
	if(!p[p[x].fail].s) return p[x].fail=Nxt(p[x].fail);
	else return p[x].fail;
}
int main(){
//    freopen("B.in","r",stdin);
//    freopen("B.out","w",stdout);
    scanf("%d",&n);p[0].dep=0;
    for(int i=1;i<=n;i++){
        scanf("%s",s);
        L[i]=strlen(s);
        build(i);
    }
    get_fail();f[0]=1;
    scanf("%s",s+1);
    int len=strlen(s+1),t=0;//return 0;
    for(int i=1;i<=len;i++){
        t=p[t].son[s[i]-'a'];
        for(int j=t;j;j=Nxt(j)){
//        	printf("%d %d\n",i,p[j].num);
        	if(p[j].s) add(f[i],p[j].s>1?1ll*f[i-p[j].dep]*p[j].s%mod:f[i-p[j].dep]);
		}
    }
    printf("%d\n",f[len]);
    return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 32692
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll in()
{
    ll re=0,f=1;char x=getchar();
    while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();}
    while(x>='0'&&x<='9')re=re*10+x-48,x=getchar();
    return re*f;
}
void out(ll x)
{
    if(x<0)putchar('-'),x=-x;
    if(!x){putchar('0');return;}
    char z[21],ct=0;
    while(x){z[++ct]=x%10+48,x/=10;}
    while(ct){putchar(z[ct]);--ct;}
}
int n;
char ss[500000];
int s[100010],pt;
int len[100010],tlen;
char t[100010];
int ptr=1;
const ll mod=1e9+7;
struct node{
    int ch[26],fa;
    char v;
    vector<int>cnt;
}nd[200010];
void ins(int l,int len)
{
    int cur=1;
    for(int i=l;i<l+len;++i)
    {
        char c=ss[i];
        if(!nd[cur].ch[c-'a'])
        {
            nd[cur].ch[c-'a']=++ptr;
            nd[ptr].fa=cur;
            nd[ptr].v=c;
        }
        cur=nd[cur].ch[c-'a'];
    }
    nd[cur].cnt.push_back(len);
}
int fail[200010];
void bfs()
{
    queue<int>q;
    fail[1]=1;
    for(int i=0;i<26;++i)
    if(nd[1].ch[i])
    {
        fail[nd[1].ch[i]]=1;
        q.push(nd[1].ch[i]);
    }
    else nd[1].ch[i]=1;
    while(!q.empty())
    {
        int h=q.front();q.pop();
        for(int i=0;i<26;++i)
        if(nd[h].ch[i])
        {
            fail[nd[h].ch[i]]=nd[fail[h]].ch[i];
            q.push(nd[h].ch[i]);
        }
        else nd[h].ch[i]=nd[fail[h]].ch[i];
    }
}
ll dp[200010];
int main()
{
    scanf("%d\n",&n);
    for(int i=1;i<=n;++i)
    {
        scanf("%s",ss+pt);
        s[i]=pt;
        len[i]=strlen(ss+pt);
        pt=pt+len[i]+1;
    }
    for(int i=1;i<=n;++i)
        ins(s[i],len[i]);
    bfs();
    scanf("%s",t+1);
    tlen=strlen(t+1);
    dp[0]=1;
    int cur=1;
    for(int i=1;i<=tlen;++i)
    {
        cur=nd[cur].ch[t[i]-'a'];
        int now=cur;
        while(now>1)
        {
            vector<int>&v=nd[now].cnt;
            for(int j=0;j<v.size();++j)
                dp[i]=(dp[i]+dp[i-v[j]])%mod;
            now=fail[now];
        }
    }
    cout<<dp[tlen]<<'\n';
}
accuracy: 1
time_ms: 1480
memory_kb: 32752
final_rank: 18

code_snippet: #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<unordered_set>
using namespace std;
const int N = 200005,se = 29 ,mod = 998244353,md=1000000007;
int n,hsh[N],mi[N],mi2[N],hh[N],m,dp[N],zy[N];
char s[N];
unordered_set<int> st,st2;
inline int hs1(int l,int r)
{
	return (hsh[r]-1ll*hsh[l-1]*mi[r-l+1]%mod+mod)%mod;
}
inline int hs2(int l,int r)
{
	return (hh[r]-1ll*hh[l-1]*mi2[r-l+1]%md+md)%md;
}
inline int plu(int x,int y) { x+=y; if (x>=md) x-=md; return x; }
int main()
{
	//freopen("a.in","r",stdin);
	mi[0]=mi2[0]=1;
	for (int i=1;i<=200000;i++)
	 mi[i]=1ll*mi[i-1]*se%mod,
	 mi2[i]=1ll*mi2[i-1]*se%md;
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	{
		int tp=0,tp2=0; scanf("%s",s+1); m=strlen(s+1);
		zy[++zy[0]]=m;
		for (int j=1;j<=m;j++)
		 tp=(1ll*tp*se%mod+s[j]-'a'+1)%mod,
		 tp2=(1ll*tp2*se%md+s[j]-'a'+1)%md;
		st.insert(tp); st2.insert(tp2);
		//cout<<tp<<" "<<tp2<<endl;
	}
	sort(zy+1,zy+n+1); int tp=1;
	for (int i=2;i<=n;i++) if (zy[i]!=zy[tp]) zy[++tp]=zy[i];
	scanf("%s",s+1); m=strlen(s+1);
	for (int i=1;i<=m;i++)
	 hsh[i]=(1ll*hsh[i-1]*se%mod+s[i]-'a'+1)%mod,
	 hh[i]=(1ll*hh[i-1]*se%md+s[i]-'a'+1)%md;
	dp[0]=1;
	for (int i=1;i<=m;i++)
	{
		for (int j=1;j<=tp&&i-zy[j]>=0;j++)
		{
			//cout<<zy[j]<<" "<<i<<" "<<hs1(i-zy[j]+1,i)<<" "<<hs2(i-zy[j]+1,i)<<endl;
			if ((st.find(hs1(i-zy[j]+1,i))!=st.end())
			&& (st2.find(hs2(i-zy[j]+1,i))!=st2.end()))
			 dp[i]=plu(dp[i],dp[i-zy[j]]);
		}
	}
	printf("%d\n",dp[m]);
	return 0;
}
accuracy: 1
time_ms: 1360
memory_kb: 8208
final_rank: 16

code_snippet: #include <bits/stdc++.h>
#define N 300010
#define M
#define K 131LL
#define P 1000000007
#define rep(i,l,r) for (int i=(l);i<=(r);i++)
#define per(i,r,l) for (int i=(r);i>=(l);i--)
#define ll long long
using namespace std;
int n,m,cnt(0),len[N],l,Cnt(0);
int f[N];
unordered_map <int,int> has;
ll h[N],pw[N];
char s[N],z[N];

int gethash(int l,int r){
	return (h[l]-h[r+1]*pw[r-l+1]%P+P)%P;
}

void pre(){
	h[n+1]=0;
	per(i,n,1)
		h[i]=((int)s[i]-(int)('a')+1+h[i+1]*K%P)%P;
	pw[0]=1;
	rep(i,1,n)
		pw[i]=pw[i-1]*K%P;
}

int gethash_(int l){
	h[n+1]=0;
	ll x=0;
	per(i,l,1)
		x=((int)z[i]-(int)('a')+1+x*K%P)%P;
	return x;
}

int main(){
//	freopen("b.in","r",stdin);
	scanf("%d",&m);
	for (int i=1;i<=m;i++){
			scanf("%s",z+1);
			++cnt;
			len[cnt]=strlen(z+1);
			has[gethash_(len[cnt])]=1;
		//	cerr << gethash_(S,len[cnt]) << endl;
		}
	sort(len+1,len+1+cnt);
	l=unique(len+1,len+1+cnt)-len-1;
	scanf("%s",s+1);
//	cout << s.length() << ' '<< s[0];
	n=strlen(s+1);
	pre();
	f[0]=1;
	for (register int i=1;i<=n;i++)
		for (register int j=1;j<=l;j++){
			if (len[j]>i) break;
		//	cerr << gethash(i-len[j]+1,i) << endl;
			if (has.count(gethash(i-len[j]+1,i))){
				f[i]+=f[i-len[j]];
				if (f[i]>=P) f[i]-=P;
			}
		}
	printf("%d\n",f[n]);
	return 0;
}
accuracy: 1
time_ms: 1100
memory_kb: 9184
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define Maxn 200007
#define modp1 998244353
#define modp2 100000007
#define modp 1000000007
int n,m;
char s[Maxn];
int len[Maxn];
int h[Maxn][2],ha[Maxn][2];
unordered_map<long long,bool> mp;
int f[Maxn];
int que[Maxn];
int bin[Maxn][2];
int calc1(int lx,int rx)
{
	return (ha[rx][0]-(1LL*ha[lx-1][0]*bin[rx-lx+1][0])%modp1+modp1)%modp1;
}
int calc2(int lx,int rx)
{
	return (ha[rx][1]-(1LL*ha[lx-1][1]*bin[rx-lx+1][1])%modp2+modp2)%modp2;
}
long long calc(int a,int b)
{
	return 1LL*a*modp2+b;
}
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	{
		scanf("%s",s+1);
		len[i]=strlen(s+1);
		for (int j=1;j<=len[i];j++)
		{
			h[i][0]=(27LL*h[i][0]+s[j]-'a'+1)%modp1;
			h[i][1]=(27LL*h[i][1]+s[j]-'a'+1)%modp2;
		}
	}
	bin[0][0]=1,bin[0][1]=1;
	for (int i=1;i<=200000;i++)
	{
		bin[i][0]=(27LL*bin[i-1][0])%modp1;
		bin[i][1]=(27LL*bin[i-1][1])%modp2;
	}
	scanf("%s",s+1);
	m=strlen(s+1);
	for (int i=1;i<=m;i++)
	{
		ha[i][0]=(27LL*ha[i-1][0]+s[i]-'a'+1)%modp1;
		ha[i][1]=(27LL*ha[i-1][1]+s[i]-'a'+1)%modp2;
	}
	for (int i=1;i<=n;i++)
	{
		que[i]=len[i];
		mp[calc(h[i][0],h[i][1])]=true;
	}
	sort(que+1,que+n+1);
	int cnt=1;
	for (int i=2;i<=n;i++)
		if (que[i]!=que[cnt]) que[++cnt]=que[i];
	f[0]=1;
	for (int i=1;i<=m;i++)
	{
		for (int j=1;j<=cnt&&que[j]<=i;j++)
			if (mp[calc(calc1(i-que[j]+1,i),calc2(i-que[j]+1,i))]) f[i]=(f[i]+f[i-que[j]])%modp;
	}
	printf("%d\n",(f[m]+modp)%modp);
	return 0;
}
accuracy: 1
time_ms: 1920
memory_kb: 251540
final_rank: 20

code_snippet: #include <bits/stdc++.h>
#define Sqrt 400
#define N 200500
#define mod 1000000007
using namespace std;
char s[N],t[N];
map <long long,int> mp1[Sqrt+5];
long long P1=233,mod1=1e9+7,fac1[N],h1[N],has1[N];
int n,tot,l,f[N],len[N];
long long gh1(int l,int r){return (has1[r]-has1[l-1]*fac1[r-l+1]%mod1+mod1)%mod1;}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%s",s+1);
		len[++tot]=strlen(s+1);
		h1[tot]=0;
		for(int j=1;j<=len[tot];j++)
			h1[tot]=(h1[tot]*P1+s[j])%mod1;
		if(len[tot]<=Sqrt){
			mp1[len[tot]][h1[tot]]=1;
			tot--;
		}
	}
	scanf("%s",t+1);
	l=strlen(t+1);
	for(int i=1;i<=l;i++)
		has1[i]=(has1[i-1]*P1+t[i])%mod1;
		
	fac1[0]=1;
	for(int i=1;i<=l;i++)
		fac1[i]=fac1[i-1]*P1%mod1;
	
	f[0]=1;
	for(int i=1;i<=l;i++){
		for(int j=1;j<=i&&j<=Sqrt;j++)
			if(mp1[j].count(gh1(i-j+1,i)))(f[i]+=f[i-j])%=mod;
		for(int j=1;j<=tot;j++)
			if(len[j]<=i&&gh1(i-len[j]+1,i)==h1[j])(f[i]+=f[i-len[j]])%=mod;
	}
	printf("%d\n",f[l]);
	return 0;
}
accuracy: 1
time_ms: 1060
memory_kb: 9912
final_rank: 7

code_snippet: #include <bits/stdc++.h>
#define N 300010
#define M
#define K 131LL
#define P 1000000007
#define rep(i,l,r) for (int i=(l);i<=(r);i++)
#define per(i,r,l) for (int i=(r);i>=(l);i--)
#define ll long long
using namespace std;
int n,m,cnt(0),len[N],l,Cnt(0);
int f[N];
unordered_set <int> has;
ll h[N],pw[N];
char s[N],z[N];

int gethash(int l,int r){
	return (h[l]-h[r+1]*pw[r-l+1]%P+P)%P;
}

void pre(){
	h[n+1]=0;
	per(i,n,1)
		h[i]=((int)s[i]-(int)('a')+1+h[i+1]*K%P)%P;
	pw[0]=1;
	rep(i,1,n)
		pw[i]=pw[i-1]*K%P;
}

int gethash_(int l){
	h[n+1]=0;
	ll x=0;
	per(i,l,1)
		x=((int)z[i]-(int)('a')+1+x*K%P)%P;
	return x;
}

int main(){
//	freopen("b.in","r",stdin);
	scanf("%d",&m);
	for (int i=1;i<=m;i++){
			scanf("%s",z+1);
			++cnt;
			len[cnt]=strlen(z+1);
			has.insert(gethash_(len[cnt]));
		//	cerr << gethash_(S,len[cnt]) << endl;
		}
	sort(len+1,len+1+cnt);
	l=unique(len+1,len+1+cnt)-len-1;
	scanf("%s",s+1);
//	cout << s.length() << ' '<< s[0];
	n=strlen(s+1);
	pre();
	f[0]=1;
	for (register int i=1;i<=n;i++)
		for (register int j=1;j<=l;j++){
			if (len[j]>i) break;
		//	cerr << gethash(i-len[j]+1,i) << endl;
			if (has.count(gethash(i-len[j]+1,i))){
				f[i]+=f[i-len[j]];
				if (f[i]>=P) f[i]-=P;
			}
		}
	printf("%d\n",f[n]);
	return 0;
}
accuracy: 1
time_ms: 1100
memory_kb: 9180
final_rank: 8

code_snippet: #include <bits/stdc++.h>
#define N 300010
#define M
#define K 131LL
#define P 1000000007
#define rep(i,l,r) for (int i=(l);i<=(r);i++)
#define per(i,r,l) for (int i=(r);i>=(l);i--)
#define ll long long
using namespace std;
int n,m,cnt(0),len[N],l,Cnt(0);
int f[N];
unordered_map <int,int> has;
ll h[N],pw[N];
char s[N],z[N];

int gethash(int l,int r){
	return (h[l]-h[r+1]*pw[r-l+1]%P+P)%P;
}

void pre(){
	h[n+1]=0;
	per(i,n,1)
		h[i]=((int)s[i]-(int)('a')+1+h[i+1]*K%P)%P;
	pw[0]=1;
	rep(i,1,n)
		pw[i]=pw[i-1]*K%P;
}

int gethash_(int l){
	h[n+1]=0;
	ll x=0;
	per(i,l,1)
		x=((int)z[i]-(int)('a')+1+x*K%P)%P;
	return x;
}

int main(){
//	freopen("b.in","r",stdin);
	scanf("%d",&m);
	for (int i=1;i<=m;i++){
			scanf("%s",z+1);
			++cnt;
			len[cnt]=strlen(z+1);
			has[gethash_(len[cnt])]=1;
		//	cerr << gethash_(S,len[cnt]) << endl;
		}
	sort(len+1,len+1+cnt);
	l=unique(len+1,len+1+cnt)-len-1;
	scanf("%s",s+1);
//	cout << s.length() << ' '<< s[0];
	n=strlen(s+1);
	pre();
	f[0]=1;
	for (register int i=1;i<=n;i++)
		for (register int j=1;j<=l;j++){
			if (len[j]>i) break;
		//	cerr << gethash(i-len[j]+1,i) << endl;
			if(f[i-len[j]])if (has[gethash(i-len[j]+1,i)]){
				f[i]+=f[i-len[j]];
				if (f[i]>=P) f[i]-=P;
			}
		}
	printf("%d\n",f[n]);
	return 0;
}
accuracy: 1
time_ms: 970
memory_kb: 15028
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define Maxn 200007
#define modp1 998244353
#define modp2 100000007
#define modp 1000000007
int n,m;
char s[Maxn];
int len[Maxn];
int h[Maxn][2],ha[Maxn][2];
unordered_map<long long,bool> mp[Maxn];
int f[Maxn];
int que[Maxn];
int bin[Maxn][2];
int calc1(int lx,int rx)
{
	return (ha[rx][0]-(1LL*ha[lx-1][0]*bin[rx-lx+1][0])%modp1+modp1)%modp1;
}
int calc2(int lx,int rx)
{
	return (ha[rx][1]-(1LL*ha[lx-1][1]*bin[rx-lx+1][1])%modp2+modp2)%modp2;
}
long long calc(int a,int b)
{
	return 1LL*a*modp2+b;
}
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	{
		scanf("%s",s+1);
		len[i]=strlen(s+1);
		for (int j=1;j<=len[i];j++)
		{
			h[i][0]=(27LL*h[i][0]+s[j]-'a'+1)%modp1;
			h[i][1]=(27LL*h[i][1]+s[j]-'a'+1)%modp2;
		}
	}
	bin[0][0]=1,bin[0][1]=1;
	for (int i=1;i<=200000;i++)
	{
		bin[i][0]=(27LL*bin[i-1][0])%modp1;
		bin[i][1]=(27LL*bin[i-1][1])%modp2;
	}
	scanf("%s",s+1);
	m=strlen(s+1);
	for (int i=1;i<=m;i++)
	{
		ha[i][0]=(27LL*ha[i-1][0]+s[i]-'a'+1)%modp1;
		ha[i][1]=(27LL*ha[i-1][1]+s[i]-'a'+1)%modp2;
	}
	for (int i=1;i<=n;i++)
	{
		que[i]=len[i];
		mp[len[i]][h[i][0]]=true;
	}
	sort(que+1,que+n+1);
	int cnt=1;
	for (int i=2;i<=n;i++)
		if (que[i]!=que[cnt]) que[++cnt]=que[i];
	f[0]=1;
	for (int i=1;i<=m;i++)
	{
		for (int j=1;j<=cnt&&que[j]<=i;j++)
			if(f[i-que[j]])if (mp[que[j]][calc1(i-que[j]+1,i)]) f[i]=(f[i]+f[i-que[j]])%modp;
	}
	printf("%d\n",(f[m]+modp)%modp);
	return 0;
}
accuracy: 1
time_ms: 850
memory_kb: 26944
final_rank: 5

code_snippet: #include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<math.h>
#include<queue>
using namespace std;
typedef long long ll;
const int N=1e5+10;
const ll mod=1000000009;
const ll p=31ll;
char str[N];
vector<ll>vec[N];int sz[N];
int lenq[N];bool used[N];
ll hh[N],pw[N],f[N];
ll gethash(int l,int r){return ((hh[r]-hh[l-1]*pw[r-l+1])%mod+mod)%mod;}
bool check(int len,ll Hash)
{
    int l=0,r=sz[len]-1;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(vec[len][mid]==Hash) return true;
        if(vec[len][mid]<Hash) l=mid+1;
        else r=mid-1;
    }
    return false;
}
const ll mod2=1000000007ll;
int main()
{
    int n,cnt=0;scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",str+1);
        int len=strlen(str+1);
        if(!used[len]) lenq[++cnt]=len;
        used[len]=true;
        ll Hash=0ll;
        for(int j=1;j<=len;j++) Hash=(Hash*p+ll(str[j]-'a'+1))%mod;
        vec[len].push_back(Hash);sz[len]++;
    }
    sort(lenq+1,lenq+cnt+1);
    for(int i=1;i<=100000;i++)
    if(used[i]) sort(vec[i].begin(),vec[i].end());
    scanf("%s",str+1);
    int m=strlen(str+1);
    hh[0]=0ll;pw[0]=1ll;
    for(int i=1;i<=m;i++)
    {
        hh[i]=(hh[i-1]*p+ll(str[i]-'a'+1))%mod;
        pw[i]=(pw[i-1]*p)%mod;
    }
    f[0]=1ll;
    for(int i=1;i<=m;i++)
    {
        f[i]=0ll;
        for(int j=1;j<=cnt&&lenq[j]<=i;j++)
        if(f[i-lenq[j]]!=0ll)
        {
            ll Hash=gethash(i-lenq[j]+1,i);
            if(check(lenq[j],Hash)) f[i]+=f[i-lenq[j]];
        }
        f[i]%=mod2;
    }
    printf("%lld\n",f[m]);
    return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 9324
final_rank: 1