Cod sursa(job #3162576)

Utilizator Teodor94Teodor Plop Teodor94 Data 29 octombrie 2023 13:58:33
Problema Potrivirea sirurilor Scor 16
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.3 kb
// sursa Robert Badea

#include <iostream>
#include <fstream>
#include <queue>
#include <vector>

using namespace std;

#define MOD1 8474635
#define BASE1 73
#define MOD2 5856358
#define BASE2 93
#define int long long

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

string str, pattern;
vector<int>v;

int lgput(int x, int pow, int mod)
{
    if(pow == 1)
    {
        return x;
    }

    if(pow % 2 == 0)
        return lgput((long long)x * x % mod, pow / 2, mod);
    return (long long)x * lgput((long long)x * x % mod, pow / 2, mod) % mod;
}

struct susta
{
    int val1, val2;
    queue<char> Q;
    susta(int x1, int x2)
    {
        val1 = x1;
        val2 = x2;
    }

    void mod()
    {
        val1 %= MOD1;
        val2 %= MOD2;
    }

    void add(char a)
    {
        Q.push(a);
        val1 = val1 * BASE1 % MOD1 + a - 'A' + 1;
        val2 = val2 * BASE2 % MOD2 + a - 'A' + 1;
        mod();
    }

    void removeLast()
    {
        val1 -= ((Q.front() - 'A' + 1) * lgput(BASE1, pattern.size(), MOD1) % MOD1);
        val2 -= ((Q.front() - 'A' + 1) * lgput(BASE2, pattern.size(), MOD2) % MOD2);
        cout << "lgput1 - " << lgput(BASE1, pattern.size(), MOD1) << '\n';
        cout << "lgput2 - " << lgput(BASE2, pattern.size(), MOD2) << '\n';
        mod();
        Q.pop();
    }

    bool operator==(susta other) const{
        return val1 == other.val1 && val2 == other.val2;
    }

    void write()
    {
        cout << Q.front() << " ";
        cout << val1 << " " << val2 << '\n';
    }

};

signed main()
{
    susta p(0,0), s(0,0);
    in >> pattern >> str;
    int i = 0;
    while(i < pattern.size())
    {
        p.add(pattern[i]);
        s.add(str[i]);
        i++;
    }
    int ans = 0;
    if(s == p)
    {
        ans = 1;
        v.push_back(0);
    }
    s.add(str[i]);
    cout << p.val1 << " " << p.val2 << '\n';
    s.write();
    for(i = pattern.size() ; i < str.size(); ++i)
    {
        s.removeLast();
        s.write();
        if(s == p)
        {
            ans++;
            if(ans < 1000)
                v.push_back(i - pattern.size() + 1);
        }
        s.add(str[i + 1]);
    }
    out << ans << '\n';
    for(auto i : v)
        out << i << " ";
    return 0;
}