Cod sursa(job #2698426)

Utilizator VladNANegoita Vlad-Andrei VladNA Data 22 ianuarie 2021 09:24:15
Problema Potrivirea sirurilor Scor 38
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.88 kb
#include <bits/stdc++.h>
#define LMAX 2000000

using namespace std;

///'A' corespunde lui 0

const int p1=197, b1=137;
const int p2=199, b2=139;

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

char A[5+LMAX], B[5+LMAX];

int ridput(int x, int putere, int mod)
{
    long long rez=1;
    while(putere)
    {
        if(putere%2)
        {
            rez=(rez*x)%mod;
            putere--;
        }
        else
        {
            putere/=2;
            x=(x*x)%mod;
        }
    }
    return rez;
}

int invmod(int x, int p)
{
    return ridput(x,p-2,p);
}

vector<int>rasp;

int main()
{
    int n,m;
    in.getline(A,LMAX+2);
    in.getline(B,LMAX+2);
    n=strlen(A);
    m=strlen(B);
    if(n>m)
    {
        out<<"0";
        return 0;
    }
    int exp1=1,exp2=1,hash1B=0,hash2B=0,hash1A=0,hash2A=0,cnt=0;
    for(int i=0;i<n;i++)
    {
        hash1A=(hash1A+exp1*(A[i]-'A'))%p1;
        hash2A=(hash2A+exp2*(A[i]-'A'))%p2;
        hash1B=(hash1B+exp1*(B[i]-'A'))%p1;
        hash2B=(hash2B+exp2*(B[i]-'A'))%p2;
        exp1=(exp1*b1)%p1;
        exp2=(exp2*b2)%p2;
    }
    int inv1=invmod(b1,p1),inv2=invmod(b2,p2);
    exp1=exp1*inv1;
    exp2=exp2*inv2;
    if(hash1A==hash1B && hash2A==hash2B)
    {
        cnt++;
        rasp.push_back(0);
    }
    for(int i=1; i<m-n+1; i++)
    {
        hash1B=(hash1B-(B[i-1]-'A')+p1)%p1;
        hash2B=(hash2B-(B[i-1]-'A')+p2)%p2;
        hash1B=(hash1B*inv1)%p1;
        hash2B=(hash2B*inv2)%p2;
        hash1B=(hash1B+(B[i+n-1]-'A')*exp1)%p1;
        hash2B=(hash2B+(B[i+n-1]-'A')*exp2)%p2;
        if(hash1A==hash1B && hash2A==hash2B)
        {
            cnt++;
            if(rasp.size()<1000)
                rasp.push_back(i);
        }
    }
    out<<cnt<<'\n';
    for(int i=0; i<1000 && i<rasp.size();i++)
        out<<rasp[i]<<' ';
    return 0;
}