Mai intai trebuie sa te autentifici.
Cod sursa(job #2725926)
Utilizator | Data | 19 martie 2021 21:04:40 | |
---|---|---|---|
Problema | Potrivirea sirurilor | Scor | 78 |
Compilator | cpp-64 | Status | done |
Runda | Arhiva educationala | Marime | 2.04 kb |
#include <cstdint>
#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 int64_t kBase = 26;
constexpr int64_t kMod = 1 << 25;
int64_t Power(int64_t base, int64_t exp) {
if (exp == 0) {
return 1;
} else if (exp == 1) {
return base % kMod;
}
if (exp % 2 == 1) {
return (base % kMod * Power(base, exp - 1)) % kMod;
}
auto root = Power(base, exp / 2);
return (root * root) % kMod;
}
int64_t Hash(const string& str) {
int64_t hash = 0;
for (const auto& ch : str) {
hash = (hash * kBase + (ch - 'A')) % kMod;
}
return hash;
}
Result Solve(const string& needle, const string& haystack) {
int64_t needle_hash = Hash(needle);
int64_t curr_hash = Hash(haystack.substr(0, needle.size() - 1));
int64_t pow = Power(kBase, needle.size() - 1);
Result res;
for (size_t i = needle.size() - 1; i < haystack.size(); i += 1) {
curr_hash = (curr_hash * kBase % kMod + (haystack[i] - 'A')) % kMod;
auto l = i + 1 - needle.size();
auto same = curr_hash == needle_hash
&& needle == haystack.substr(l, needle.size());
if (same) {
res.AddMatch(l);
}
curr_hash = (curr_hash - pow * (haystack[l] - 'A') % kMod) % 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;
}