Cod sursa(job #2675191)

Utilizator SoranaAureliaCatrina Sorana SoranaAurelia Data 21 noiembrie 2020 11:04:33
Problema Potrivirea sirurilor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.84 kb
#include <fstream>
#include <array>
#include <cstring>
#include <vector>
#define NMAX 2000005
#define MOD1 100003
#define MOD2 100109
using namespace std;


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

typedef long long lli;

char a[NMAX], b[NMAX];
int nr=0, sol[NMAX];

struct Hash{
    int NMOD;
    int a=31;
    lli power, hashh;
    Hash(int nmod){
        NMOD = nmod;
    }

    void init(char *s, lli len){
        power = 1;
        hashh = 0;
        for(int i = len-1; i>=0; i--){
            hashh = (hashh + (1LL*power*s[i])%NMOD)%NMOD;
            if(i)
                power = (power*a)%NMOD;
        }
    }

    void roll(char toRemove, char toAdd){
        hashh = (((hashh - (toRemove*power)%NMOD)%NMOD + NMOD)*a + toAdd)%NMOD;
    }

    bool operator==(const Hash &other) const{
        return hashh == other.hashh;
    }
};

vector<int> find_matches(){

    int n=strlen(a), m=strlen(b);
    array<Hash, 2> hash_pattern{Hash(MOD1), Hash(MOD2)};
    array<Hash, 2> hash_text{Hash(MOD1), Hash(MOD2)};

    if(n>m)
        return {};
    for(int i=0; i<2; i++){
        hash_pattern[i].init(a, n);
        hash_text[i].init(b, n);
    }

    vector<int>matches;
    if(hash_pattern[0] == hash_text[0] && hash_pattern[1] == hash_text[1])
        matches.push_back(0);
    for(int i=n; i<m; i++){
        for(int k=0; k<2; k++){
            hash_text[k].roll(b[i-n], b[i]);
        }
        if(hash_pattern[0] == hash_text[0] && hash_pattern[1] == hash_text[1])
            matches.push_back(i-n+1);
    }
    return matches;
}
int main()
{
    f.getline(a, NMAX);
    f.getline(b, NMAX);
    vector<int> match = find_matches();
    g<<match.size()<<'\n';
    int nr = match.size();
    nr=min(1000, nr);
    for(int i=0; i<nr; i++)
        g<<match[i]<<' ';

    return 0;
}