Cod sursa(job #3243703)

Utilizator StasBrega Stanislav Stas Data 20 septembrie 2024 14:53:36
Problema Potrivirea sirurilor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 5.82 kb
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

namespace
{
#define ll long long
#define int ll
#undef INT_MAX
#define INT_MAX LLONG_MAX
#define ull unsigned long long
#define PI acos(-1)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define vi vector<int>
#define vll vector<ll>
#define vpii vector<pii>
#define vvpii vector<vector<pii>>
#define vvi vector<vector<int>>
#define vf vector<long double>
#define vvf vector<vector<long double>>
#define cmplxd complex<double>
#define float long double
#define fs first
#define sc second
#define pb push_back
#define lsh(i) (1 << (i))
#define fi(i, n) for (int i = 0; (i) < (n); ++(i))
#define fe(x, a) for (auto &x : (a))
#define all(a) (a).begin(), (a).end()
#define YES (cout << "YES\n")
#define NO (cout << "NO\n")
#define endl '\n'
#define gcd(a, b) __gcd(a, b)
    const int mod = (1e9 + 7);
    const int pmod = 998244353;
    const int altmod = 999999937;

    using namespace __gnu_pbds;
    using namespace std;

    template <typename T>
    using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

    struct custom_hash
    {
        static uint64_t splitmix64(uint64_t x)
        {
            x += 0x9e3779b97f4a7c15;
            x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
            x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
            return x ^ (x >> 31);
        }
        size_t operator()(uint64_t x) const
        {
            static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
            return splitmix64(x + FIXED_RANDOM);
        }
        size_t operator()(pair<uint64_t, uint64_t> x) const
        {
            static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
            return splitmix64(x.first + FIXED_RANDOM) ^ (splitmix64(x.second + FIXED_RANDOM) >> 1);
        }
    };
#define us unordered_set<int, custom_hash>
#define um unordered_map<int, int, custom_hash>
    void multiply(vvi &Z, vvi B)
    {
        int N = Z.size();
        vvi A(Z);
        Z = vvi(N, vi(N, 0));
        fi(i, N)
            fi(j, N)
                fi(k, N)
                    Z[i][j] = (Z[i][j] + 1ll * A[i][k] * B[k][j] % altmod) % altmod;
    }
    [[maybe_unused]] void f(vvi &Z, int n)
    {
        vvi aux(Z);
        while (n)
        {
            if (n % 2)
                multiply(Z, aux);
            multiply(aux, aux);
            n /= 2;
        }
    }
}

signed char dp[300][300][300][2];

void solve()
{
    int l, n, m;

    cin >> l >> n >> m;

    vi b(l);
    fe(x, b)
    {
        cin >> x;
    }

    vvi a(n, vi(m));
    map<int, vector<pair<int, int>>> poz;
    fi(i, n)
    {
        fi(j, m)
        {
            cin >> a[i][j];
            poz[a[i][j]].push_back({i, j});
        }
    }

    fi(a1, l)
    {
        fi(a2, n)
        {
            fi(a3, m)
            {
                fi(a4, 2)
                {
                    dp[a1][a2][a3][a4] = -1;
                }
            }
        }
    }

    function<bool(int, int, int, bool)> f = [&](int p, int i, int j, bool ok)
    {
        if (p == b.size() || i >= n || j >= m)
        {
            return !ok;
        }

        if (dp[p][i][j][ok] != -1)
        {
            return dp[p][i][j][ok] == 1;
        }

        dp[p][i][j][ok] = ok ? 0 : 1;

        auto &pozArr = poz[b[p]];

        for (auto [x, y] : pozArr)
        {
            if (x >= i && y >= j)
            {
                if (ok)
                {
                    dp[p][i][j][ok] = max(dp[p][i][j][ok], static_cast<signed char>(f(p + 1, x + 1, y + 1, !ok) ? 1 : 0));
                    if (dp[p][i][j][ok] == 1)
                    {
                        return true;
                    }
                }
                else
                {
                    dp[p][i][j][ok] = min(dp[p][i][j][ok], static_cast<signed char>(f(p + 1, x + 1, y + 1, !ok) ? 1 : 0));
                    if (dp[p][i][j][ok] == 0)
                    {
                        return false;
                    }
                }
            }
        }

        return dp[p][i][j][ok] == 1;
    };

    cout << (f(0, 0, 0, true) ? "T" : "N") << endl;
}

signed main()
{
#ifndef ONLINE_JUDGE
    freopen("strmatch.in", "r", stdin);
    freopen("strmatch.out", "w", stdout);
#endif // ! ONLINE_JUDGE
    ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);
    cout.tie(nullptr);

    // int t;
    // cin >> t;

    // while (t--)
    // {
    //     solve();
    // }

    string s, t;
    cin >> t >> s;

    int P = 62;
    int h1 = 0, h2 = 0;
    int mod1 = pmod, mod2 = altmod;
    int p1 = 1, p2 = 1;

    for (int i = 0; t[i]; ++i)
    {
        h1 = ((h1 * P) + t[i]) % mod1;
        h2 = ((h2 * P) + t[i]) % mod2;

        if (i)
        {
            p1 = (p1 * P) % mod1;
            p2 = (p2 * P) % mod2;
        }
    }

    int hs1 = 0, hs2 = 0;
    for (int i = 0; i < t.size(); ++i)
    {
        hs1 = ((hs1 * P) + s[i]) % mod1;
        hs2 = ((hs2 * P) + s[i]) % mod2;
    }

    vector<int> ans;
    if (h1 == hs1 && h2 == hs2)
    {
        ans.push_back(0);
    }

    for (int i = t.size(); s[i]; ++i)
    {
        hs1 = (hs1 - s[i - t.size()] * p1 + mod1) % mod1;
        hs1 = (hs1 * P + s[i]) % mod1;

        hs2 = (hs2 - s[i - t.size()] * p1 + mod1) % mod1;
        hs2 = (hs2 * P + s[i]) % mod1;

        if (h1 == hs1 && h2 == hs2)
        {
            ans.push_back(i - t.size() + 1);
        }
    }

    cout << ans.size() << endl;
    for (int i = 0; i < min(1000ull, ans.size()); ++i)
    {
        cout << ans[i] << " ";
    }

    return 0;
}