QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#843111#9970. Looping RPSucup-team133#RE 0ms3668kbC++237.3kb2025-01-04 16:51:452025-01-04 16:51:51

Judging History

你现在查看的是最新测评结果

  • [2025-01-04 16:51:51]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:3668kb
  • [2025-01-04 16:51:45]
  • 提交

answer

#include <bits/stdc++.h>
#ifdef LOCAL
#include <debug.hpp>
#else
#define debug(...) void(0)
#endif

template <class T, class U = T> bool chmin(T& x, U&& y) {
    return y < x and (x = std::forward<U>(y), true);
}

template <class T, class U = T> bool chmax(T& x, U&& y) {
    return x < y and (x = std::forward<U>(y), true);
}

template <class T> void mkuni(std::vector<T>& v) {
    std::ranges::sort(v);
    auto result = std::ranges::unique(v);
    v.erase(result.begin(), result.end());
}

template <class T> int lwb(const std::vector<T>& v, const T& x) {
    return std::distance(v.begin(), std::ranges::lower_bound(v, x));
}

namespace hash_impl {

static constexpr unsigned long long mod = (1ULL << 61) - 1;

struct modint {
    modint() : _v(0) {}
    modint(long long v) {
        unsigned long long vv = v < 0 ? v + mod : v;
        vv = (vv >> 61) + (vv & mod);
        if (vv >= mod) vv -= mod;
        _v = vv;
    }

    unsigned long long val() const { return _v; }

    modint& operator+=(const modint& rhs) {
        _v += rhs._v;
        if (_v >= mod) _v -= mod;
        return *this;
    }
    modint& operator-=(const modint& rhs) {
        if (_v < rhs._v) _v += mod;
        _v -= rhs._v;
        return *this;
    }
    modint& operator*=(const modint& rhs) {
        __uint128_t t = __uint128_t(_v) * rhs._v;
        t = (t >> 61) + (t & mod);
        if (t >= mod) t -= mod;
        _v = t;
        return *this;
    }
    modint& operator/=(const modint& rhs) { return *this = *this * rhs.inv(); }

    modint operator-() const { return modint() - *this; }

    modint pow(long long n) const {
        assert(0 <= n);
        modint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    modint inv() const { return pow(mod - 2); }

    friend modint operator+(const modint& lhs, const modint& rhs) { return modint(lhs) += rhs; }
    friend modint operator-(const modint& lhs, const modint& rhs) { return modint(lhs) -= rhs; }
    friend modint operator*(const modint& lhs, const modint& rhs) { return modint(lhs) *= rhs; }
    friend modint operator/(const modint& lhs, const modint& rhs) { return modint(lhs) /= rhs; }
    friend bool operator==(const modint& lhs, const modint& rhs) { return lhs._v == rhs._v; }
    friend bool operator!=(const modint& lhs, const modint& rhs) { return lhs._v != rhs._v; }
    friend std::ostream& operator<<(std::ostream& os, const modint& rhs) {
        os << rhs._v;
        return os;
    }

  private:
    unsigned long long _v;
};

uint64_t generate_base() {
    std::mt19937_64 mt(std::chrono::steady_clock::now().time_since_epoch().count());
    std::uniform_int_distribution<uint64_t> rand(2, mod - 1);
    return rand(mt);
}

modint base(generate_base());
std::vector<modint> power{1};

modint get_pow(int n) {
    if (n < int(power.size())) return power[n];
    int m = power.size();
    power.resize(n + 1);
    for (int i = m; i <= n; i++) power[i] = power[i - 1] * base;
    return power[n];
}

};  // namespace hash_impl

struct Hash {
    using mint = hash_impl::modint;
    mint x;
    int len;

    Hash() : x(0), len(0) {}
    Hash(mint x) : x(x), len(1) {}
    Hash(mint x, int len) : x(x), len(len) {}

    Hash& operator+=(const Hash& rhs) {
        x = x * hash_impl::get_pow(rhs.len) + rhs.x;
        len += rhs.len;
        return *this;
    }
    Hash operator+(const Hash& rhs) const { return Hash(*this) += rhs; }
    bool operator==(const Hash& rhs) const { return x == rhs.x and len == rhs.len; }
};

struct ReversibleHash {
    using mint = hash_impl::modint;
    mint x, rx;
    int len;

    ReversibleHash() : x(0), rx(0), len(0) {}
    ReversibleHash(mint x) : x(x), rx(x), len(1) {}
    ReversibleHash(mint x, mint rx, int len) : x(x), rx(rx), len(len) {}

    ReversibleHash rev() const { return ReversibleHash(rx, x, len); }

    ReversibleHash operator+=(const ReversibleHash& rhs) {
        x = x * hash_impl::get_pow(rhs.len) + rhs.x;
        rx = rx + rhs.rx * hash_impl::get_pow(len);
        len += rhs.len;
        return *this;
    }
    ReversibleHash operator+(const ReversibleHash& rhs) const { return ReversibleHash(*this) += rhs; }
    bool operator==(const ReversibleHash& rhs) const { return x == rhs.x and rx == rhs.rx and len == rhs.len; }
};

using namespace std;

using ll = long long;

using mint = hash_impl::modint;

void solve() {
    int n;
    cin >> n;
    vector<string> S(n);
    for (int i = 0; i < n; i++) {
        cin >> S[i];
    }

    vector<vector<mint>> hashes(n);
    for (int i = 0; i < n; i++) {
        hashes[i].emplace_back(0);
        for (char& c : S[i]) {
            hashes[i].emplace_back(hashes[i].back() * hash_impl::base + c);
        }
    }

    auto f = [&](int i, int j, int len) -> mint {
        assert(int(S[i].size() + S[j].size()) >= len);
        int tmp = S[i].size();
        if (len <= tmp) {
            return hashes[i][len];
        }
        return hashes[i].back() * hash_impl::get_pow(len - tmp) + hashes[j][len - tmp];
    };
    auto lcp = [&](int i, int j) -> int {
        int lb = 0, ub = int(S[i].size() + S[j].size()) + 1;
        while (ub - lb > 1) {
            int mid = (lb + ub) >> 1;
            (f(i, j, mid) == f(j, i, mid) ? lb : ub) = mid;
        }
        return lb;
    };
    {
        vector<int> ord(n);
        iota(ord.begin(), ord.end(), 0);
        ranges::sort(ord, [&](int i, int j) {
            int l1 = S[i].size(), l2 = S[j].size();
            int l = lcp(i, j);
            if (l == l1 + l2) {
                return false;
            }
            return S[l % l1] < S[l % l2];
        });
        vector<string> nS(n);
        for (int i = 0; i < n; i++) {
            nS[i] = S[ord[i]];
        }
        swap(S, nS);

        vector<vector<mint>> nhashes(n);
        for (int i = 0; i < n; i++) {
            nhashes[i].emplace_back(0);
            for (char& c : S[i]) {
                nhashes[i].emplace_back(nhashes[i].back() * hash_impl::base + c);
            }
        }
        swap(hashes, nhashes);
    }

    ll ans = 0;
    auto dfs = [&](auto self, int l, int r) -> void {
        if (r - l < 3) {
            return;
        }
        int len = lcp(l, r - 1);
        if (len == int(S[l].size() + S[r - 1].size())) {
            return;
        }
        int m1, m2;
        {
            int lb = l, ub = r;
            while (ub - lb > 1) {
                int mid = (lb + ub) >> 1;
                if (int(S[l].size() + S[mid].size()) < len + 1) {
                    lb = mid;
                } else {
                    (f(l, mid, len + 1) == f(mid, l, len + 1) ? lb : ub) = mid;
                }
            }
            m1 = ub;
            assert(ub < r);
        }
        {
            int lb = m1, ub = r;
            while (ub - lb > 1) {
                int mid = (lb + ub) >> 1;
                if (int(S[l].size() + S[mid].size()) < len + 1) {
                    lb = mid;
                } else {
                    (f(l, mid, len + 1) == f(mid, l, len + 1) ? lb : ub) = mid;
                }
            }
            m2 = ub;
        }
        ans += 1LL * (m1 - l) * (m2 - m1) * (r - m2);
        self(self, l, m1);
        self(self, m1, m2);
        self(self, m2, r);
    };
    dfs(dfs, 0, n);

    cout << ans << "\n";
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    solve();
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3668kb

input:

6
P
PN
KK
N
PKK
PN

output:

6

result:

ok 1 number(s): "6"

Test #2:

score: -100
Runtime Error

input:

10
KKKNP
KNKPPKNK
KNKPP
KNKPPKN
KKKN
NNKNNNKNNNKNNNKNNNKNNNKNNNKNNPN
NNKN
NPPN
NNKNNNKNNNKNNNKNNNKNNNKNNNK
KKKNN

output:


result: