Pagini recente » Cod sursa (job #384040) | Cod sursa (job #3280968) | Cod sursa (job #1649708) | Cod sursa (job #2026058) | Cod sursa (job #2237890)
#include <bits/stdc++.h>
using namespace std;
// String Hasher
template <int B, int MOD>
struct Hasher {
// Static array of powers of B
static vector <int> pows;
static void resize(int newSz) {
if (newSz > pows.size()) {
const int oldSz = pows.size();
pows.resize(newSz);
for (int i = oldSz; i < newSz; ++i)
pows[i] = ((1LL * B * pows[i - 1]) % MOD);
}
}
static int getPow(int pw) {
while (pw >= (int)pows.size())
resize(2 * pows.size());
return pows[pw];
}
// Data members
int h, sz;
// Constructors
Hasher(): h(0), sz(0) {}
Hasher(int ch): h(ch), sz(1) {}
Hasher(int _h, int _sz): h(_h), sz(_sz) {}
// Pushes
void push_back(int ch) { h = (1LL * h * B + ch) % MOD, ++sz; }
void push_front(int ch) { h = (1LL * ch * getPow(sz) + h) % MOD, ++sz; }
// Pops
void pop_back(int ch) {
--sz;
h = (h - ch) % MOD;
if (h < 0) h += MOD;
}
void pop_front(int ch) {
--sz;
h = (h - 1LL * getPow(sz) * ch) % MOD;
if (h < 0) h += MOD;
}
// Concatenation
friend Hasher operator+(const Hasher &a, const Hasher &b) { return Hasher((1LL * a.h * getPow(b.sz) + b.h) % MOD, a.sz + b.sz); }
// Comparison
friend bool operator==(const Hasher &a, const Hasher &b) { return make_pair(a.h, a.sz) == make_pair(b.h, b.sz); }
};
template <int B, int MOD>
vector <int> Hasher <B, MOD> :: pows = {1};
typedef Hasher <263, 1000000000 + 7> H1;
typedef Hasher <277, 1000000000 + 9> H2;
int main() {
ifstream cin("strmatch.in");
ofstream cout("strmatch.out");
string pattern, str;
cin >> pattern >> str;
H1 :: resize(pattern.size());
H2 :: resize(pattern.size());
H1 h_pat1, h1;
H2 h_pat2, h2;
for (auto it: pattern) {
h_pat1.push_back(it);
h_pat2.push_back(it);
}
vector <int> ans;
for (int i = 0; i < str.size(); ++ i) {
h1.push_back(str[i]);
h2.push_back(str[i]);
if (i >= pattern.size() - 1) {
if (h1 == h_pat1 && h2 == h_pat2)
ans.push_back(i - pattern.size() + 1);
h1.pop_front(str[i - pattern.size() + 1]);
h2.pop_front(str[i - pattern.size() + 1]);
}
}
cout << ans.size() << '\n';
if (ans.size() > 1000)
ans.resize(1000);
for (int i = 0; i < ans.size(); ++ i)
cout << ans[i] << " \n"[i + 1 == ans.size()];
return 0;
}