Cod sursa(job #2739048)

Utilizator redstonegamer22Andrei Ion redstonegamer22 Data 6 aprilie 2021 18:56:38
Problema Potrivirea sirurilor Scor 92
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.55 kb
#include <bits/stdc++.h>

using namespace std;

#ifndef LOCAL

ifstream in("strmatch.in");
ofstream out("strmatch.out");

#define cin in
#define cout out

#endif //LOCAL

const int base = 59;
const int mod1 = 1e9 + 7;
const int mod2 = 1e9 + 9;

int ctoi(char ch)
{
    return ch - 64;
}

int main()
{
    string a, b;
    cin >> a >> b;
    if(a.size() > b.size())
    {
        cout << 0 << endl;
        return 0;
    }

    pair<int, int> hashA{0, 0};
    int powBase1 = 1;
    int powBase2 = 1;

    for(auto ch : a)
    {
        hashA.first = (1LL * hashA.first * base + ctoi(ch)) % mod1;
        hashA.second = (1LL * hashA.second * base + ctoi(ch)) % mod2;
        powBase1 = (1LL * powBase1 * base) % mod1;
        powBase2 = (1LL * powBase2 * base) % mod2;
    }

    #ifdef LOCAL
        cout << hashA.first << " " << hashA.second << endl;
    #endif //LOCAL

    int nrMatches = 0;
    
    pair<int, int> cntHashB{0, 0};
    for(int i = 0; i < a.size(); i++)
    {
        cntHashB.first = (1LL * cntHashB.first * base + ctoi(b[i])) % mod1;
        cntHashB.second = (1LL * cntHashB.second * base + ctoi(b[i])) % mod2;
    
        if(cntHashB == hashA)
            ++nrMatches;
    }

    for(int i = a.size(); i < b.size(); i++)
    {
        cntHashB.first = (1LL * cntHashB.first * base + ctoi(b[i]) - 1LL * powBase1 * ctoi(b[i - a.size()]) + 1LL * mod1 * mod1) % mod1;
        cntHashB.second = (1LL * cntHashB.second * base + ctoi(b[i]) - 1LL * powBase2 * ctoi(b[i - a.size()]) + 1LL * mod2 * mod2) % mod2;

        #ifdef LOCAL
            cout << cntHashB.first << " " << cntHashB.second << endl;
        #endif //LOCAL

        if(cntHashB == hashA)
            ++nrMatches;
    }

    cout << nrMatches << endl;

    nrMatches = min(1000, nrMatches);
    cntHashB = {0, 0};

    for(int i = 0; i < a.size(); i++)
    {
        cntHashB.first = (1LL * cntHashB.first * base + ctoi(b[i])) % mod1;
        cntHashB.second = (1LL * cntHashB.second * base + ctoi(b[i])) % mod2;
    
        if(cntHashB == hashA && nrMatches)
        {
            nrMatches--;
            cout << i + 1 - a.size() << " ";
        }
    }

    for(int i = a.size(); i < b.size(); i++)
    {
        cntHashB.first = (1LL * cntHashB.first * base + ctoi(b[i]) - 1LL * powBase1 * ctoi(b[i - a.size()]) + 1LL * mod1 * mod1) % mod1;
        cntHashB.second = (1LL * cntHashB.second * base + ctoi(b[i]) - 1LL * powBase2 * ctoi(b[i - a.size()]) + 1LL * mod2 * mod2) % mod2;

        if(cntHashB == hashA && nrMatches)
        {
            nrMatches--;
            cout << i + 1 - a.size() << " ";
        }
    }
}