Pagini recente » Istoria paginii runda/simulareoji2020/clasament | Cod sursa (job #959843) | Cod sursa (job #842090) | Istoria paginii runda/adasd/clasament | Cod sursa (job #2725939)
#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 = 73;
constexpr int64_t kMod1 = 100007;
constexpr int64_t kMod2 = 100021;
int64_t Power(int64_t base, int64_t exp, int64_t mod) {
if (exp == 0) {
return 1;
} else if (exp == 1) {
return base % mod;
}
if (exp % 2 == 1) {
return (base % mod * Power(base, exp - 1, mod)) % mod;
}
auto root = Power(base, exp / 2, mod);
return (root * root) % mod;
}
int64_t Advance(int64_t hash, char ch, int64_t mod) {
return (hash * kBase % mod + (ch - 'A')) % mod;
}
int64_t Hash(const string& str, int64_t mod) {
int64_t hash = 0;
for (const auto& ch : str) {
hash = Advance(hash, ch, mod);
}
return hash;
}
Result Solve(const string& needle, const string& haystack) {
int64_t needle_hash1 = Hash(needle, kMod1);
int64_t needle_hash2 = Hash(needle, kMod2);
int64_t pow1 = Power(kBase, needle.size() - 1, kMod1);
int64_t pow2 = Power(kBase, needle.size() - 1, kMod2);
int64_t hash1 = Hash(haystack.substr(0, needle.size() - 1), kMod1);
int64_t hash2 = Hash(haystack.substr(0, needle.size() - 1), kMod2);
Result res;
for (size_t i = needle.size() - 1; i < haystack.size(); i += 1) {
hash1 = Advance(hash1, haystack[i], kMod1);
hash2 = Advance(hash2, haystack[i], kMod2);
auto l = i + 1 - needle.size();
auto same = hash1 == needle_hash1
&& hash2 == needle_hash2
&& needle == haystack.substr(l, needle.size());
if (same) {
res.AddMatch(l);
}
hash1 = (hash1 + kMod1 - pow1 * (haystack[l] - 'A') % kMod1) % kMod1;
hash2 = (hash2 + kMod2 - pow2 * (haystack[l] - 'A') % kMod2) % kMod2;
}
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;
}