11const int modulus = 1e9 + 7;
 
   20size_t compute_hash(
const std::string& str, 
size_t start, 
size_t end) {
 
   22    size_t hash_value = 0;
 
   23    for (
size_t i = start; i < end; i++) {
 
   24        hash_value = (hash_value + (size_t(str[end - i - 1]) * curr_mod) % modulus) % modulus;
 
   25        curr_mod = (curr_mod * base) % modulus;
 
   46bool check_collision(
const std::string& str1, 
size_t start1, 
const std::string& str2, 
size_t start2,
 
   48    for (
size_t i = 0; i < length; ++i) {
 
   49        if (str1[start1 + i] != str2[start2 + i]) {
 
   70std::vector<size_t> rabin_karp(
const std::string& text, 
const std::string& pattern) {
 
   71    std::vector<size_t> result;
 
   72    size_t pattern_length = pattern.length();
 
   73    size_t text_length = text.length();
 
   75    if (pattern_length == 0) { 
 
   77        for (
size_t i = 0; i <= text_length; i++) {
 
   83    if (text_length < pattern_length) { 
 
   90    size_t pattern_hash = compute_hash(pattern, 0, pattern_length);
 
   91    size_t text_hash = compute_hash(text, 0, pattern_length);
 
   95    for (
int i = 0; i < pattern_length - 1; ++i)
 
   96        power = (power * base) % modulus;
 
   98    for (
size_t i = 0; i <= text_length - pattern_length; ++i) {
 
   99        if (pattern_hash == text_hash && check_collision(text, i, pattern, 0, pattern_length)) {
 
  103        if (i < text_length - pattern_length) {
 
  105                (base * (text_hash - ((size_t)text[i] * power % modulus) + modulus) % modulus +
 
  106                 (size_t)text[i + pattern_length]) %