Cod sursa(job #3303151)

Utilizator Cristian_NegoitaCristian Negoita Cristian_Negoita Data 14 iulie 2025 12:41:17
Problema Potrivirea sirurilor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.25 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("strmatch.in");
ofstream fout("strmatch.out");
const int BASE = 63, MOD1 = 1e9 + 7, MOD2 = 1e9 + 9;

inline int char_to_number(const char ch)
{
    if(isalpha(ch))
        return (islower(ch) ? (ch - 'a' + 1) : (ch - 'A' + 27));
    return (ch - '0' + 53);
}

vector<int> rabin_karp(const string &pattern, const string &text)
{
    int pattern_hash1 = 0, pattern_hash2 = 0;
    for(int i = 0; i < pattern.size(); i++)
    {
        pattern_hash1 = (1LL * BASE * pattern_hash1 + char_to_number(pattern[i])) % MOD1;
        pattern_hash2 = (1LL * BASE * pattern_hash2 + char_to_number(pattern[i])) % MOD2;
    }
    int text_hash1 = 0, text_hash2 = 0;
    for(int i = 0; i < pattern.size(); i++)
    {
        text_hash1 = (1LL * BASE * text_hash1 + char_to_number(text[i])) % MOD1;
        text_hash2 = (1LL * BASE * text_hash2 + char_to_number(text[i])) % MOD2;
    }
    vector<int> positions;
    if(pattern_hash1 == text_hash1 && pattern_hash2 == text_hash2)
        positions.push_back(0);
    vector<int> pwr1(pattern.size()), pwr2(pattern.size());
    pwr1[0] = pwr2[0] = 1;
    for(int i = 1; i < pattern.size(); i++)
    {
        pwr1[i] = (1LL * BASE * pwr1[i - 1]) % MOD1;
        pwr2[i] = (1LL * BASE * pwr2[i - 1]) % MOD2;
    }
    for(int i = pattern.size(); i < text.size(); i++)
    {
        text_hash1 = (text_hash1 - (1LL * char_to_number(text[i - pattern.size()]) * pwr1[pattern.size() - 1]) % MOD1 + MOD1) % MOD1;
        text_hash1 = (1LL * text_hash1 * BASE + char_to_number(text[i])) % MOD1;
        text_hash2 = (text_hash2 - (1LL * char_to_number(text[i - pattern.size()]) * pwr2[pattern.size() - 1]) % MOD2 + MOD2) % MOD2;
        text_hash2 = (1LL * text_hash2 * BASE + char_to_number(text[i])) % MOD2;
        if(pattern_hash1 == text_hash1 && pattern_hash2 == text_hash2)
            positions.push_back(i - pattern.size() + 1);
    }
    return positions;
}

int main()
{
    string pattern, text;
    fin >> pattern >> text;
    vector<int> ans = rabin_karp(pattern, text);
    fout << ans.size() << "\n";
    for(int i = 0; i < min(1000, (int)ans.size()); i++)
        fout << ans[i] << " ";

    fin.close();
    fout.close();
    return 0;
}