답안 #586564

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
586564 2022-06-30T11:45:28 Z leeh18 Osmosmjerka (COCI17_osmosmjerka) C++17
80 / 160
4000 ms 25388 KB
#include <bits/stdc++.h>

template<__int128 p, __int128 m>
struct hash_string {
    static std::vector<__int128> power;
    std::vector<__int128> p_hash;
    hash_string(const std::string& s) : p_hash(s.size()+1, 0) {
        for (int i = 0; i < (int)s.size(); i++) {
            p_hash[i+1] = (p_hash[i] * p + s[i]) % m;
        }
    }
    __int128 pow(int i) {
        while (i >= (int)power.size()) {
            auto val = power.back();
            val = val * p % m;
            power.push_back(val);
        }
        return power[i];
    }
    __int128 pow(__int128 x, int i) {
        if (i == 0) return 1;
        auto ret = pow(x, i/2);
        ret = ret * ret % m;
        if (i & 1) ret = ret * x % m;
        return ret;
    }
    __int128 pow_sum(__int128 x, int i) {
        if (i == 1) return 1;
        auto ret = pow_sum(x, i/2);
        ret = (1 + pow(x, i/2)) % m * ret % m;
        if (i & 1) {
            ret = ret * x % m;
            ret = (ret + x) % m;
        }
        return ret;
    }
    __int128 hash(int l, int r) { // [l, r] inclusive
        auto ret = p_hash[r+1] - p_hash[l] * pow(r-l+1) % m;
        ret = (ret + m) % m;
        return ret;
    }
    __int128 hash(int l, int r, int k) {
        int n = r - l + 1;
        __int128 ret = 0;
        if (k / n != 0) {
            ret = hash(l, r) * pow_sum(pow(n), k/n) % m;
        }
        if (k % n != 0) {
            ret = ret * pow(k % n) % m + hash(l, l + k % n - 1);
            ret %= m;
        }
        return ret;
    }
};

template<__int128 p, __int128 m>
std::vector<__int128> hash_string<p, m>::power {1};

struct hash_string2 {
    hash_string<9973, 9223372036854775783LL> s1;
    hash_string<9973, 9223372036854775643LL> s2;
    hash_string2(const std::string& s) : s1(s), s2(s) {}
    __int128 hash(int l, int r, int k) {
        return (s1.hash(l, r, k) << 64) | s2.hash(l, r, k);
    }
};

constexpr auto max = 501;
bool visited[max][max][4];

int main() {
    std::cin.tie(0)->sync_with_stdio(0);
    int n, m, k;
    std::cin >> n >> m >> k;
    std::vector<std::string> v(n);
    for (auto &s : v) {
        std::cin >> s;
    }
    std::map<__int128, int64_t> cnt;
    auto update = [&](std::pair<int, int> start, int t) -> void {
        const std::array<std::pair<int, int>, 4> direction {{{1, 0}, {1, 1}, {1, -1}, {0, 1}}};
        auto [row, col] = start;
        if (visited[row][col][t]) return;
        const auto [dr, dc] = direction[t];
        std::string s;
        while (!visited[row][col][t]) {
            visited[row][col][t] = true;
            s.push_back(v[row][col]);
            row = (row + dr + n) % n;
            col = (col + dc + m) % m;
        }
        int sz = int(std::size(s));
        s += s;
        hash_string<9973, 1000000009> hs(s);
        for (int i = 0; i < sz; i++) {
            auto hash = hs.hash(i, i+sz-1, k);
            ++cnt[hash];
        }
        std::reverse(s.begin(), s.end());
        hash_string<9973, 1000000009> hs_reversed(s);
        for (int i = 0; i < sz; i++) {
            auto hash = hs_reversed.hash(i, i+sz-1, k);
            ++cnt[hash];
        }
    };
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            for (int t = 0; t < 4; t++) {
                update({i, j}, t);
            }
        }
    }
    int64_t p = 0;
    int64_t q = 64 * n * n * m * m;
    for (auto [key, val] : cnt) {
        p += val * val;
    }
    auto g = std::gcd(p, q);
    std::cout << p/g << '/' << q/g << '\n';
}
# 결과 실행 시간 메모리 Grader output
1 Incorrect 1 ms 212 KB Output isn't correct
2 Correct 1 ms 340 KB Output is correct
3 Correct 1 ms 340 KB Output is correct
4 Correct 3 ms 340 KB Output is correct
5 Correct 25 ms 680 KB Output is correct
6 Incorrect 118 ms 4108 KB Output isn't correct
7 Incorrect 1251 ms 25388 KB Output isn't correct
8 Execution timed out 4058 ms 23852 KB Time limit exceeded