Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- using namespace std;
- typedef long long ll;
- const int N = 505;
- const int P1 = 17;
- const int P2 = 13;
- const int MOD = 1e9 + 7;
- char a[N][N], s[2][N][N], pattern[2][2];
- int n, m;
- ll ha[N][N], hs[N][N], pw1[N], pw2[N];
- void build(int mask)
- {
- for (int i = 0; i < 2; ++i)
- for (int j = 0; j < 2; ++j)
- {
- pattern[i][j] = s[0][i][j] = (mask % 2 ? '*' : '.');
- mask /= 2;
- }
- }
- bool next(bool& w, int& x)
- {
- if (2 * x > n || 2 * x > m) return false;
- for (int i = 0; i < x; ++i)
- for (int j = 0; j < x; ++j)
- if (s[w][i][j] == '*') s[!w][2 * i][2 * j] = s[!w][2 * i + 1][2 * j] = s[!w][2 * i][2 * j + 1] = s[!w][2 * i + 1][2 * j + 1] = '*';
- else
- {
- s[!w][2 * i][2 * j] = pattern[0][0];
- s[!w][2 * i + 1][2 * j] = pattern[1][0];
- s[!w][2 * i][2 * j + 1] = pattern[0][1];
- s[!w][2 * i + 1][2 * j + 1] = pattern[1][1];
- }
- w = !w;
- x *= 2;
- return true;
- }
- void buildHash(char aa[N][N], ll h[N][N], int nn, int mm)
- {
- for (int i = 0; i < nn; ++i)
- for (int j = 0; j < mm; ++j)
- {
- int bit = (aa[i][j] == '*') + 1;
- h[i][j] = pw1[i] * bit % MOD * pw2[j] % MOD + (i ? h[i - 1][j] : 0) + (j ? h[i][j - 1] : 0) - (i && j ? h[i - 1][j - 1] : 0);
- h[i][j] %= MOD;
- if (h[i][j] < 0) h[i][j] += MOD;
- }
- }
- int find(bool w, int x)
- {
- int cnt = 0;
- for (int i = 0; i <= n - x; ++i)
- for (int j = 0; j <= m - x; ++j)
- {
- ll resa = ha[i + x - 1][j + x - 1] - (i ? ha[i - 1][j + x - 1] : 0) - (j ? ha[i + x - 1][j - 1] : 0) + (i && j ? ha[i - 1][j - 1] : 0);
- resa %= MOD;
- if (resa < 0) resa += MOD;
- resa = resa * pw1[n - i] % MOD;
- resa = resa * pw2[m - j] % MOD;
- ll resb = hs[x - 1][x - 1];
- resb = resb * pw1[n] % MOD;
- resb = resb * pw2[m] % MOD;
- cnt += resa == resb;
- }
- return cnt;
- }
- int main()
- {
- cin >> n >> m;
- getchar();
- for (int i = 0; i < n; ++i, getchar())
- for (int j = 0; j < m; ++j)
- a[i][j] = getchar();
- pw1[0] = pw2[0] = 1;
- for (int i = 1; i < N; ++i)
- {
- pw1[i] = pw1[i - 1] * P1 % MOD;
- pw2[i] = pw2[i - 1] * P2 % MOD;
- }
- buildHash(a, ha, n, m);
- int ans = 0;
- for (int i = 0; i < 16; ++i)
- {
- build(i);
- bool w = 0;
- int x = 2;
- while (next(w, x))
- {
- buildHash(s[w], hs, x, x);
- ans += find(w, x);
- }
- }
- cout << ans;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement