Cod sursa(job #2985386)

Utilizator stefandutastefandutahoria stefanduta Data 26 februarie 2023 13:44:04
Problema Prefix Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.66 kb
#include <fstream>
#include <cstring>
#define BASE 260
#define MOD1 666013
#define MOD2 777013
#define NMAX 1000005

using namespace std;

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

char s[NMAX];

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

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

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

int main()
{
    int t, n, i, j;
    in >> t;
    in.get();
    while (t--)
    {
        in.getline(s, NMAX);
        long long h1p = 0, h1d = 0, h2p = 0, h2d = 0, put1 = 1, put2 = 1, poz1 = 0, poz2 = 1, maxx1 = 0, maxx2 = 0, hash1, hash2, lungime = 0;
        int n = strlen(s);
        if (n > 1)
        {
            h1p = adauga_hash(h1p, s[0], MOD1);
            h2p = adauga_hash(h2p, s[0], MOD2);

            h1d = adauga_hash(h1d, s[1], MOD1);
            h2d = adauga_hash(h2d, s[1], MOD2);
            if (h1p == h1d && h2p == h2d)
            {
                maxx1 = poz1;
                maxx2 = poz2;
            }
            while (poz2 < n - 2)
            {
                ++poz1;
                h1p = adauga_hash(h1p, s[poz1], MOD1);
                h2p = adauga_hash(h2p, s[poz1], MOD2);

                h1d = scoate_hash(h1d, s[poz1], put1, MOD1);
                h2d = scoate_hash(h2d, s[poz1], put2, MOD2);

                ++poz2;
                h1d = adauga_hash(h1d, s[poz2], MOD1);
                h2d = adauga_hash(h2d, s[poz2], MOD2);

                ++poz2;
                h1d = adauga_hash(h1d, s[poz2], MOD1);
                h2d = adauga_hash(h2d, s[poz2], MOD2);

                put1 = (put1 * BASE) % MOD1;
                put2 = (put2 * BASE) % MOD2;

                if (h1p == h1d && h2p == h2d)
                {
                    maxx1 = poz1;
                    maxx2 = poz2;
                    hash1 = h1p;
                    hash2 = h2p;
                }
            }

            //out << maxx1 << " " << maxx2 << '\n';

            h1p = hash1;
            h2p = hash2;

            if (maxx2 != 0)
            {
                lungime = maxx2 + 1;
                while (maxx2 + maxx1 + 1 < n && hash1 == h1p && hash2 == h2p)
                {
                    h1p = 0;
                    h2p = 0;
                    for (i = maxx2 + 1; i <= maxx2 + maxx1 + 1; ++i)
                    {
                        h1p = adauga_hash(h1p, s[i], MOD1);
                        h2p = adauga_hash(h2p, s[i], MOD2);
                    }

                    if (hash1 == h1p && hash2 == h2p)
                    {
                        maxx2 = maxx2 + maxx1 + 1;
                        lungime = lungime + maxx1 + 1;
                    }
                }
                if (maxx2 + maxx1 + 2 >= n)
                {
                    for (i = maxx2 + 1; i < n; ++i)
                    {
                        bool x = true;
                        for (j = 0; j <= maxx1; ++j)
                        {
                            if (s[j] != s[i])
                                x = false;
                        }
                        if (x == true)
                            ++lungime;
                    }
                }
            }
            out << lungime << '\n';
        }
        else
            out << 0 << '\n';
    }
    return 0;
}