Cod sursa(job #3303797)

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

using namespace std;

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

inline constexpr std::array<int, 3> kPrimeMods = {1000003, 1000033, 1000039};

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 patterLength = pattern.size();
    int textLength = text.size();
    if (patterLength > 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 < patterLength; ++j)
        {
            textHashes[i] = (textHashes[i] * P + (text[j])) % kPrimeMods[i];
        }

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

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

    int i = 0;
    do
    {
        bool match = true;
        for (size_t j = 0; j < kPrimeMods.size(); ++j)
        {
            if (textHashes[j] != patternHashes[j])
            {
                match = false;
                break;
            }
        }
        if (match)
        {
            assert(i + patterLength <= textLength);
            if (text.substr(i, patterLength) == pattern)
            {
                result.push_back(i);
            }
        }
        i++;

        if (i < textLength - patterLength + 1)
        {
            for (size_t j = 0; j < kPrimeMods.size(); ++j)
            {
                textHashes[j] -= (text[i - 1]) * maxPower[j];
                textHashes[j] += kPrimeMods[j]; // Ensure non-negative
                textHashes[j] %= kPrimeMods[j];
                textHashes[j] *= P;
                textHashes[j] += kPrimeMods[j];
                textHashes[j] %= kPrimeMods[j];
                textHashes[j] += (text[i + patterLength - 1]);
                textHashes[j] += kPrimeMods[j];
                textHashes[j] %= kPrimeMods[j];
            }
        }
    } while (i < textLength - patterLength + 1);
}

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> patterHashes(kPrimeMods.size());
    for (size_t i = 0; i < kPrimeMods.size(); ++i)
    {
        patterHashes[i] = computePatternHash(x, kPrimeMods[i]);
    }

    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] << ' ';
    }
}