Cod sursa(job #2725909)

Utilizator preda.andreiPreda Andrei preda.andrei Data 19 martie 2021 20:40:42
Problema Potrivirea sirurilor Scor 78
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.03 kb
#include <fstream>
#include <string>
#include <vector>

using namespace std;

class Result {
public:
    void AddMatch(int pos);

    friend ostream& operator<<(ostream& os, const Result& res);

private:
    vector<int> matches_;
    int match_count_ = 0;
};

void Result::AddMatch(int pos) {
    if (matches_.size() < 1000) {
        matches_.push_back(pos);
    }
    match_count_ += 1;
}

ostream& operator<<(ostream& os, const Result& res) {
    os << res.match_count_ << "\n";
    for (const auto& pos : res.matches_) {
        os << pos << " ";
    }
    os << "\n";
    return os;
}

constexpr auto kBase = 26;
constexpr auto kMod = 1 << 25;

int Power(int base, int exp) {
    if (exp == 0) {
        return 1;
    } else if (exp == 1) {
        return base % kMod;
    }

    if (exp % 2 == 1) {
        return (1LL * base % kMod * Power(base, exp / 2)) % kMod;
    }

    auto root = Power(base, exp / 2);
    return (1LL * root * root) % kMod;
}

int Hash(const string& str) {
    auto hash = 0;
    for (const auto& ch : str) {
        hash = (hash * kBase + (ch - 'A')) % kMod;
    }
    return hash;
}

Result Solve(const string& needle, const string& haystack) {
    auto needle_hash = Hash(needle);
    auto curr_hash = 0;

    auto pow = Power(kBase, needle.size());

    Result res;
    for (size_t i = 0; i < haystack.size(); i += 1) {
        curr_hash = (1LL * curr_hash * kBase + (haystack[i] - 'A')) % kMod;
        if (i + 1 < needle.size()) {
            continue;
        }

        auto l = i + 1 - needle.size();
        if (curr_hash == needle_hash && i + 1 >= needle.size()) {
            if (needle == haystack.substr(l, needle.size())) {
                res.AddMatch(l);
            }
        }
        curr_hash = (1LL * curr_hash - pow * (haystack[l] - 'A')) % kMod;
    }
    return res;
}

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

    string needle, haystack;
    getline(fin, needle);
    getline(fin, haystack);

    auto res = Solve(needle, haystack);
    fout << res << "\n";

    return 0;
}