Submission #713321

#TimeUsernameProblemLanguageResultExecution timeMemory
713321JohannOsmosmjerka (COCI17_osmosmjerka)C++14
160 / 160
3698 ms87380 KiB
#include "bits/stdc++.h" using namespace std; typedef long long ll; typedef pair<ll, ll> pii; typedef vector<ll> vi; typedef vector<vi> vvi; typedef vector<vvi> vvvi; typedef vector<vvvi> vvvvi; typedef vector<pii> vpii; #define sz(x) (ll)(x).size() #define all(x) (x).begin(), (x).end() const ll MOD = ((1LL << 61) - 1); const ll P = 9973; const ll P1 = 98999; const ll P2 = 22573; const ll P3 = 1367; const ll P4 = 41809; ll mod_mul(ll a, ll b) { __int128 res = (__int128)a * b; return res % MOD; } int N, M, K; vpii dirs = {{1, 1}, {1, 0}, {1, -1}, {0, 1}, {0, -1}, {-1, 1}, {-1, 0}, {-1, -1}}; int shift(int idx, int didx, int amount, int m) { return (((idx + didx * amount) % m) + m) % m; } vvi grid; vvvi dp; vi pot; int logheight; void initDPvars() { logheight = ceil(log2(K) + 1); dp.assign(N, vvi(M, vi(logheight, 0))); pot.assign(logheight, P); // pot[i] = P^(2^i) for (int l = 1; l < logheight; ++l) pot[l] = mod_mul(pot[l - 1], pot[l - 1]); } void makeDP(int di, int dj) { for (int i = 0; i < N; ++i) for (int j = 0; j < M; ++j) dp[i][j][0] = grid[i][j]; for (int l = 1; l < logheight; ++l) for (int i = 0; i < N; ++i) for (int j = 0; j < M; ++j) dp[i][j][l] = (dp[i][j][l - 1] + mod_mul(pot[l - 1], dp[shift(i, di, 1 << (l - 1), N)][shift(j, dj, 1 << (l - 1), M)][l - 1])) % MOD; } ll lift(int i, int j, int di, int dj, int k) { ll ans = 0; ll pp = 1; for (int l = 0; l < sz(dp[i][j]); ++l) { if (k & (1 << l)) { ans = (ans + mod_mul(pp, dp[i][j][l])) % MOD; pp = mod_mul(pp, pot[l]); i = shift(i, di, 1 << l, N); j = shift(j, dj, 1 << l, M); } } return ans; } int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> N >> M >> K; grid.assign(N, vi(M, 0)); for (int i = 0; i < N; ++i) { string tmp; cin >> tmp; for (int j = 0; j < M; ++j) grid[i][j] = tmp[j]; } initDPvars(); vi paths; for (int di = -1; di <= 1; ++di) for (int dj = -1; dj <= 1; ++dj) { if (di == 0 && dj == 0) continue; makeDP(di, dj); for (int i = 0; i < N; ++i) for (int j = 0; j < M; ++j) paths.push_back(lift(i, j, di, dj, K)); } sort(all(paths)); ll num = 0; ll denom = sz(paths) * sz(paths); ll last = paths.front(); ll cnt = 1; for (int i = 1; i < sz(paths); ++i) { if (paths[i] == last) ++cnt; else { num += cnt * cnt; cnt = 1; last = paths[i]; } } num += cnt * cnt; ll g = __gcd(num, denom); cout << num / g << "/" << denom / g << endl; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...