Cod sursa(job #2870064)

Utilizator stefandutastefandutahoria stefanduta Data 12 martie 2022 02:01:51
Problema Potrivirea sirurilor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.99 kb
#include <fstream>
#include <cstring>
#define HASH1 256
#define HASH2 300
#define MOD1 666013
#define MOD2 777013
#define NMAX 2000005

using namespace std;
ifstream in("strmatch.in");
ofstream out("strmatch.out");

char v[NMAX], s[NMAX];
int rez[NMAX], cnt;

int lgput(int a, int e, int mod)
{
    int p = 1;
    while (e)
    {
        if (e % 2 == 1)
            p = (long long)p * a % mod;
        a = (long long)a * a % mod;
        e = e / 2;
    }
    return p;
}

int adauga_hash(int x, char ch, int hash, int mod)
{
    return ((long long)x * hash + ch) % mod;
}

int scoate_hash(int x, char ch, int putere, int mod)
{
    x = x - (long long)ch * putere % mod;
    if (x < 0)
        x = x + mod;
    return x;
}

int main()
{
    int i, h1v = 0, h2v = 0, h1s = 0, h2s = 0, n, m;
    in.getline(v, NMAX);
    in.getline(s, NMAX);
    n = strlen(v);
    m = strlen(s);
    int putere1 = lgput(HASH1, n - 1, MOD1);
    int putere2 = lgput(HASH2, n - 1, MOD2);
    for (i = 0; i < n; ++i)
    {
        h1v = adauga_hash(h1v, v[i], HASH1, MOD1);
        h2v = adauga_hash(h2v, v[i], HASH2, MOD2);
    }

    for (i = 0; i < n - 1; ++i)
    {
        h1s = adauga_hash(h1s, s[i], HASH1, MOD1);
        h2s = adauga_hash(h2s, s[i], HASH2, MOD2);
    }

    //out << h1v << " " << h2v << '\n' << h1s << " " << h2s << '\n' << '\n';

    i = n;
    while (i <= m)
    {
        h1s = adauga_hash(h1s, s[i - 1], HASH1, MOD1);
        h2s = adauga_hash(h2s, s[i - 1], HASH2, MOD2);
        //out << h1v << " " << h2v << '\n' << h1s << " " << h2s << '\n' << s[i - n] << " " << s[i] << '\n' << '\n';

        if (h1v == h1s && h2v == h2s)
        {
            rez[++cnt] = i - n;
        }

        h1s = scoate_hash(h1s, s[i - n], putere1, MOD1);
        h2s = scoate_hash(h2s, s[i - n], putere2, MOD2);

        ++i;
    }

    out << cnt << '\n';
    for (i = 1; i <= min(cnt, 1000); ++i)
    {
        out << rez[i] << " ";
    }
    return 0;
}