Cod sursa(job #2237882)

Utilizator Andrei1998Andrei Constantinescu Andrei1998 Data 3 septembrie 2018 18:46:31
Problema Potrivirea sirurilor Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 2.11 kb
#include <bits/stdc++.h>

using namespace std;

// String Hasher
template <int B, int invB, int MOD>
struct Hasher {
    int h, pow;
    // Constructors
    Hasher(): h(0), pow(1) { assert((1LL * B * invB) % MOD == 1); }
    Hasher(int ch): h(ch), pow(B) {}
    Hasher(int _h, int _pow): h(_h), pow(_pow) {}
    // Pushes
    void push_back(int ch) { h = (1LL * h * B + ch) % MOD, pow = (1LL * pow * B) % MOD; }
    void push_front(int ch) { h = (1LL * ch * pow + h) % MOD, pow = (1LL * pow * B) % MOD; }
    // Pops
    void pop_back(int ch) {
        pow = (1LL * pow * invB) % MOD;
        h = (h - ch) % MOD;
        if (h < 0) h += MOD;
    }
    void pop_front(int ch) {
        pow = (1LL * pow * invB) % MOD;
        h = (h - 1LL * pow * ch) % MOD;
        if (h < 0) h += MOD;
    }
    // Concatenation
    friend Hasher operator+(const Hasher &a, const Hasher &b) { return Hasher((1LL * a.h * b.pow + b.h) % MOD, (1LL * a.pow * b.pow) % MOD); }
    // Comparison
    friend bool operator==(const Hasher &a, const Hasher &b) { return make_pair(a.h, a.pow) == make_pair(b.h, b.pow); }
};

typedef Hasher <263, 836501907, 1000000000 + 7> H1;
//typedef Hasher <277, 494584842, 1000000000 + 9> H2;

int main() {
    ifstream cin("strmatch.in");
    ofstream cout("strmatch.out");

    string pattern, str;
    cin >> pattern >> str;

    H1 h_pat1, h1;
    //H2 h_pat2, h2;
    h1 = h_pat1;
    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;
}