Cod sursa(job #3303811)

Utilizator robigiirimias robert robigi Data 18 iulie 2025 00:40:38
Problema Potrivirea sirurilor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.59 kb
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <array>
#include <cassert>

using namespace std;

constexpr int P = 73; // Number of characters in the input (ASCII)

inline constexpr std::array<int, 2> kPrimeMods = {100007, 100021};

int computePatternHash(const string &pattern, int mod)
{
    int hash = 0;
    for (char c : pattern)
    {
        hash = (hash * P + (c)) % mod;
    }
    return hash;
}

void findPatternOccurrences(const string &text, const string &pattern, vector<int> &result)
{
    int patternLength = pattern.size();
    int textLength = text.size();
    if (patternLength > textLength)
        return;

    vector<int> textHashes(kPrimeMods.size());
    vector<int> patternHashes(kPrimeMods.size());
    for (size_t i = 0; i < kPrimeMods.size(); ++i)
    {
        for (int j = 0; j < patternLength; ++j)
        {
            textHashes[i] = (textHashes[i] * P + (text[j])) % kPrimeMods[i];
        }

        patternHashes[i] = computePatternHash(pattern, kPrimeMods[i]);
    }

    array<int, 2> maxPower = {1, 1};
    for (size_t i = 0; i < kPrimeMods.size(); ++i)
    {
        for (int j = 0; j < patternLength - 1; ++j)
        {
            maxPower[i] = (maxPower[i] * P) % kPrimeMods[i];
        }
    }

    for (int i = 0; i < textLength - patternLength + 1;)
    {
        bool match = true;
        for (size_t j = 0; j < kPrimeMods.size(); ++j)
        {
            if (textHashes[j] != patternHashes[j])
            {
                match = false;
                break;
            }
        }
        if (match)
        {
            result.push_back(i);
            if (result.size() >= 1000)
                return;
        }
        i++;

        if (i < textLength - patternLength + 1)
        {
            for (size_t j = 0; j < kPrimeMods.size(); ++j)
            {
                long long h = textHashes[j] - 1LL * (text[i - 1]) * maxPower[j];
                h = ((h % kPrimeMods[j]) + kPrimeMods[j]) % kPrimeMods[j] * P + (text[i + patternLength - 1]);
                textHashes[j] = h % kPrimeMods[j];
            }
        }
    }
}

int main()
{
    ifstream fin("strmatch.in");
    ofstream fout("strmatch.out");

    string x, y;
    fin >> x >> y;

    if (x.size() > y.size())
    {
        fout << 0 << '\n';
        return 0;
    }

    vector<int> result;

    findPatternOccurrences(y, x, result);

    fout << result.size() << '\n';

    for (size_t i = 0; i < result.size() && i < 1000; ++i)
    {
        fout << result[i] << ' ';
    }
}