Submission #697144

#TimeUsernameProblemLanguageResultExecution timeMemory
697144omikron123Osmosmjerka (COCI17_osmosmjerka)C++14
100 / 160
4078 ms17752 KiB
// https://oj.uz/problem/view/COCI17_osmosmjerka #include <cstdio> #include <algorithm> #include <functional> #include <vector> #include <cstring> #include <map> using namespace std; typedef long long ll; typedef pair<int,int> pi; // 从任一点出发,最多LCM(M,N)个字符之后,就会出现重复的pattern,因此我们只要生成这个长度的hash,就可以找到所有唯一字符串了。 // 然后出现重复的概率,就是每个unique pattern概率的平方和。 // O(n^3) int m,n,K; // m,n <= 500, K <= 1e9 char s[505][505]; // M rows, N cols int dir[8][2] = {{0,1},{0,-1},{1,0},{-1,0},{1,1},{-1,-1},{1,-1},{-1,1}}; int hsh[8][505][505]; // hash value patterns for 8 directions int p[505]; map<int,int> cnts; // hash -> count const int A = 911382323, M = 972663749; ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a%b); } int main() { scanf("%d %d %d", &m, &n, &K); for (int i = 0; i < m; i++) scanf("%s", s[i]); int lcm = m*n/gcd(m,n); if (K > lcm) K = lcm; int step = max(m,n); p[0] = 1; for (int i = 1; i <= step; i++) p[i] = (ll)p[i-1] * A % M; for (int di = 0; di < 8; di++) // calc hash values for step-len strings from each pos for (int r = 0; r < m; r++) for (int c = 0; c < n; c++) { hsh[di][r][c] = s[r][c]; int R = r, C = c; for (int i = 0; i < step; i++) { hsh[di][r][c] = ((ll)hsh[di][r][c] * A + s[R][C]) % M; R = (R + m + dir[di][0]) % m; C = (C + n + dir[di][1]) % n; } } for (int di = 0; di < 8; di++) // calc hashes for LCM-len strings from each pos for (int r = 0; r < m; r++) for (int c = 0; c < n; c++) { int hs = 0; int R = r, C = c; for (int i = 0; i < K/step; i++) { // walk large steps hs = ((ll)hs * p[step] + hsh[di][R][C]) % M; R = (R + (ll)step*(m+dir[di][0])) % m; C = (C + (ll)step*(n+dir[di][1])) % n; } for (int i = 0; i < K%step; i++) { // remaining chars hs = ((ll)hs * A + s[R][C]) % M; R = (R + m + dir[di][0]) % m; C = (C + n + dir[di][1]) % n; } cnts[hs]++; } ll total = m*n*8; total = total*total; ll squared = 0; for (auto e: cnts) { int v = e.second; squared += (ll)v*v; } ll g = gcd(total, squared); printf("%lld/%lld", squared/g, total/g); return 0; }

Compilation message (stderr)

osmosmjerka.cpp: In function 'int main()':
osmosmjerka.cpp:30:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   30 |     scanf("%d %d %d", &m, &n, &K);
      |     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
osmosmjerka.cpp:32:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   32 |         scanf("%s", s[i]);
      |         ~~~~~^~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...