Cod sursa(job #2911273)

Utilizator maiaauUngureanu Maia maiaau Data 28 iunie 2022 12:01:44
Problema Potrivirea sirurilor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.57 kb
#include <bits/stdc++.h>
using namespace std;

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

const int N = 2e6;
const int h1 = 100007;
const int h2 = 100023;
const int p1 = 13;
const int p2 = 51;

int h1a, h2a, h1b, h2b, i, cnt;
char a[N + 5], b[N + 5];
vector<int> sol;

int logp(int b, int e, int mod){
    int p = 1;
    while(e) {
        if (e % 2) p = (1ll * p * b) % mod;
        b = (1ll * b * b) % mod;
        e /= 2;
    }
    return p;
}

int main()
{
    f >> a + 1 >> b + 1;
    
    int n = strlen(a + 1);
    int m = strlen(b + 1);
    
    if(n > m){
        g << 0;
        return 0;
    }
    
    for (i = 1; i <= n; i++){
        h1a = (h1a * p1 % h1 + int(a[i])) % h1;
        h2a = (h2a * p2 % h2 + int(a[i])) % h2;
        h1b = (h1b * p1 % h1 + int(b[i])) % h1;
        h2b = (h2b * p2 % h2 + int(b[i])) % h2;
    }
    
    if(h1a == h1b && h2a == h2b) {
        sol.push_back(0);
        cnt++;
    }    
    
    int pw1 = logp(p1, n - 1, h1);
    int pw2 = logp(p2, n - 1, h2);
    
    for (i = n + 1; i <= m; i++){
        h1b -= (1ll * int(b[i - n]) * pw1) % h1;
        while (h1b < 0) h1b += h1;
        h1b = ((1ll * h1b * p1) % h1 + b[i]) % h1;
        
        h2b -= (1ll * int(b[i - n]) * pw2) % h2;
        while (h2b < 0) h2b += h2;
        h2b = ((1ll * h2b * p2) % h2 + b[i]) % h2;
        
        if(h1b == h1a && h2b == h2a){
            cnt++;
            if(cnt <= 1000) sol.push_back(i - n);
        }
    }
    
    g << cnt << '\n';
    for (auto it: sol) g << it << ' ';
    return 0;
}

//p1^(n-1)*e1 + p1^(n-2)*e2 + ... + p1*e(n-1) + en
//