Cod sursa(job #2723579)

Utilizator vladm98Munteanu Vlad vladm98 Data 14 martie 2021 23:15:50
Problema Potrivirea sirurilor Scor 80
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.4 kb
#include <bits/stdc++.h>

using namespace std;

pair <unsigned int, unsigned int> hashes[2000005]; //hash[i] = s[i] + baza * s[i + 1] + baza ^ 2 * s[i + 2] + ... + baza ^ j * s[i + j] + ...
//Tinem o pereche pentru ca vom folosi 2 baze si 2 modulo
pair <unsigned int, unsigned int> powers[2000005]; //powers[i] = baza ^ i
pair <unsigned int, unsigned int> bases = {123, 217};

void buildHashes(string text) {
    unsigned int n = text.size();
    for (unsigned int i = n; i >= 1; --i) {
        hashes[i].first = (hashes[i + 1].first * bases.first + text[i - 1]);
        hashes[i].second = (hashes[i + 1].second * bases.second + text[i - 1]);
    }
}

void buildPowers(string text) {
    unsigned int n = text.size();
    powers[0] = {1, 1};
    for (unsigned int i = 1; i <= n; ++i) {
        powers[i].first = powers[i - 1].first * bases.first;
        powers[i].second = powers[i - 1].second * bases.second;
    }
}

pair <unsigned int, unsigned int> buildPatternHash(string pattern) {
    unsigned int n = pattern.size();
    pair <unsigned int, unsigned int> hash = {0, 0};
    for (unsigned int i = n; i >= 1; --i) {
        hash.first = (hash.first * bases.first + pattern[i - 1]);
        hash.second = (hash.second * bases.second + pattern[i - 1]);
    }
    return hash;
}

pair <unsigned int, unsigned int> buildTextHash(unsigned int left, unsigned int right) {
    return {(hashes[left].first - 1LL * hashes[right + 1].first * powers[right - left + 1].first),
            (hashes[left].second - 1LL * hashes[right + 1].second * powers[right - left + 1].second)};
}

bool patternMatch(pair <unsigned int, unsigned int> hash, unsigned int left, unsigned int right) {
    return hash == buildTextHash(left, right);
}

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

    string pattern, text;
    fin >> pattern >> text;

    buildHashes(text);
    buildPowers(text);
    pair <unsigned int, unsigned int> hash = buildPatternHash(pattern);
    unsigned int cnt = 0;
    for (unsigned int i = 1; i + pattern.size() - 1 <= text.size(); ++i) {
        if (patternMatch(hash, i, i + pattern.size() - 1)) {
            cnt += 1;
        }
    }
    fout << cnt << "\n";
    cnt = 0;
    for (unsigned int i = 1; i + pattern.size() - 1 <= text.size(); ++i) {
        if (cnt < 1000 and patternMatch(hash, i, i + pattern.size() - 1)) {
            cnt += 1;
            fout << i - 1 << " ";
        }
    }
    return 0;
}