Advertisement
Guest User

specical_for_dalex

a guest
Sep 27th, 2012
220
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.46 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. using namespace std;
  5. typedef long long ll;
  6. const int N = 505;
  7. const int P1 = 17;
  8. const int P2 = 13;
  9. const int MOD = 1e9 + 7;
  10. char a[N][N], s[2][N][N], pattern[2][2];
  11. int n, m;
  12. ll ha[N][N], hs[N][N], pw1[N], pw2[N];
  13.  
  14. void build(int mask)
  15. {
  16.   for (int i = 0; i < 2; ++i)
  17.     for (int j = 0; j < 2; ++j)
  18.     {
  19.       pattern[i][j] = s[0][i][j] = (mask % 2 ? '*' : '.');
  20.       mask /= 2;
  21.     }
  22. }
  23. bool next(bool& w, int& x)
  24. {
  25.   if (2 * x > n || 2 * x > m) return false;
  26.   for (int i = 0; i < x; ++i)
  27.     for (int j = 0; j < x; ++j)
  28.       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] = '*';
  29.       else
  30.       {
  31.         s[!w][2 * i][2 * j] = pattern[0][0];
  32.         s[!w][2 * i + 1][2 * j] = pattern[1][0];
  33.         s[!w][2 * i][2 * j + 1] = pattern[0][1];
  34.         s[!w][2 * i + 1][2 * j + 1] = pattern[1][1];
  35.       }
  36.   w = !w;
  37.   x *= 2;
  38.   return true;
  39. }
  40. void buildHash(char aa[N][N], ll h[N][N], int nn, int mm)
  41. {
  42.   for (int i = 0; i < nn; ++i)
  43.     for (int j = 0; j < mm; ++j)
  44.     {
  45.       int bit = (aa[i][j] == '*') + 1;
  46.       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);
  47.       h[i][j] %= MOD;
  48.       if (h[i][j] < 0) h[i][j] += MOD;
  49.     }
  50. }
  51. int find(bool w, int x)
  52. {
  53.   int cnt = 0;
  54.   for (int i = 0; i <= n - x; ++i)
  55.     for (int j = 0; j <= m - x; ++j)
  56.     {
  57.       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);
  58.       resa %= MOD;
  59.       if (resa < 0) resa += MOD;
  60.       resa = resa * pw1[n - i] % MOD;
  61.       resa = resa * pw2[m - j] % MOD;
  62.  
  63.       ll resb = hs[x - 1][x - 1];
  64.       resb = resb * pw1[n] % MOD;
  65.       resb = resb * pw2[m] % MOD;
  66.  
  67.       cnt += resa == resb;
  68.     }
  69.   return cnt;
  70. }
  71.  
  72. int main()
  73. {
  74.   cin >> n >> m;
  75.   getchar();
  76.   for (int i = 0; i < n; ++i, getchar())
  77.     for (int j = 0; j < m; ++j)
  78.       a[i][j] = getchar();
  79.   pw1[0] = pw2[0] = 1;
  80.   for (int i = 1; i < N; ++i)
  81.   {
  82.     pw1[i] = pw1[i - 1] * P1 % MOD;
  83.     pw2[i] = pw2[i - 1] * P2 % MOD;
  84.   }
  85.   buildHash(a, ha, n, m);
  86.   int ans = 0;
  87.   for (int i = 0; i < 16; ++i)
  88.   {
  89.     build(i);
  90.     bool w = 0;
  91.     int x = 2;
  92.     while (next(w, x))
  93.     {
  94.       buildHash(s[w], hs, x, x);
  95.       ans += find(w, x);
  96.     }
  97.   }
  98.   cout << ans;
  99.   return 0;
  100. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement