fork download
  1. #include<bits/stdc++.h>
  2.  
  3. #define INF 1000010000
  4. #define nl '\n'
  5. #define pb push_back
  6. #define ppb pop_back
  7. #define mp make_pair
  8. #define fi first
  9. #define se second
  10. #define pii pair<int,int>
  11. #define pdd pair<double,double>
  12. #define all(c) (c).begin(), (c).end()
  13. #define SORT(c) sort(all(c))
  14. #define sz(c) (c).size()
  15. #define rep(i,n) for( int i = 0; i < n; ++i )
  16. #define repi(i,n) for( int i = 1 ; i <= n; ++i )
  17. #define repn(i,n) for( int i = n - 1 ; i >= 0 ; --i )
  18. #define repf(j,i,n) for( int j = i ; j < n ; ++j )
  19. #define die(s) {std::cout << s << nl;}
  20. #define dier(s) {std::cout << s; return 0;}
  21. #define dbg(var) {std::cout << #var << " = " << var << nl;}
  22. #define vi vector<int>
  23. typedef long long ll;
  24.  
  25. using namespace std;
  26.  
  27. int cnt[1111][1111][27];
  28.  
  29. int main() {
  30. ios_base::sync_with_stdio(false);
  31. cin.tie(NULL);
  32. cout.precision(0);
  33.  
  34. int n , m;
  35. cin >> n >> m;
  36.  
  37. vector<string> v(n);
  38. for(auto& el : v) cin >> el;
  39.  
  40. rep(i , n)
  41. {
  42. rep(j , m)
  43. {
  44. ++cnt[i][j][v[i][j] - 'a'];
  45. rep(k , 26)
  46. {
  47. if(i > 0) cnt[i][j][k] += cnt[i - 1][j][k];
  48. if(j > 0) cnt[i][j][k] += cnt[i][j - 1][k];
  49. if(i > 0 && j > 0) cnt[i][j][k] -= cnt[i - 1][j - 1][k];
  50. }
  51. }
  52. }
  53.  
  54. auto get = [&](int x1 , int y1 , int x2 , int y2 , int k)
  55. {
  56. int res = cnt[x1][y1][k];
  57. if(y2 > 0) res -= cnt[x1][y2 - 1][k];
  58. if(x2 > 0) res -= cnt[x2 - 1][y1][k];
  59. if(x2 > 0 && y2 > 0) res += cnt[x2 - 1][y2 - 1][k];
  60. return res;
  61. };
  62.  
  63. ll ans = 0;
  64. rep(i , n)
  65. {
  66. rep(j , m)
  67. {
  68. int lh = 1 , rh = n - i - 1;
  69. while(rh - lh > 1)
  70. {
  71. int mid = (rh + lh) / 2;
  72. if(get(i + mid - 1, j , i , j , v[i][j] - 'a') != mid)
  73. {
  74. rh = mid;
  75. }
  76. else
  77. {
  78. lh = mid;
  79. }
  80. }
  81.  
  82. if(get(i + lh - 1, j , i , j , v[i][j] - 'a') != lh) continue;
  83.  
  84. const int h = lh;
  85. if(i + 3 * h - 1 < n)
  86. {
  87. char c1 = v[i][j];
  88. char c2 = v[i + h][j];
  89. char c3 = v[i + 2 * h][j];
  90.  
  91. if(c1 == c2 || c2 == c3) break;
  92.  
  93. bool good = true;
  94. if(get(i + h - 1, j , i , j , c1 - 'a') != h) good = false;
  95. if(get(i + 2 * h - 1 , j , i + h , j , c2 - 'a') != h) good = false;
  96. if(get(i + 3 * h - 1 , j , i + 2 * h , j , c3 - 'a') != h) good = false;
  97.  
  98.  
  99. if(good)
  100. {
  101. int l = j , r = m;
  102. while(r - l > 1)
  103. {
  104. int mid = (r + l) / 2;
  105. if(
  106. get(i + h - 1 , mid , i , j , c1 - 'a') != h * (mid - j + 1) ||
  107. get(i + 2 * h - 1 , mid , i + h , j , c2 - 'a') != h * (mid - j + 1) ||
  108. get(i + 3 * h - 1 , mid , i + 2 * h , j , c3 - 'a') != h * (mid - j + 1)
  109. )
  110. {
  111. r = mid;
  112. }
  113. else
  114. {
  115. l = mid;
  116. }
  117. }
  118.  
  119. ans += l - j + 1;
  120. }
  121. }
  122. }
  123. }
  124.  
  125. cout << ans << endl;
  126.  
  127. return 0;
  128. }
Success #stdin #stdout 0s 145408KB
stdin
10 10
aaaaarpppp
bbbbsssssu
cciiiiiiqq
ddmmgggggg
eeebbbbbbb
fffffqoooo
gxxxxrrrrr
hhfuuuuuuu
iiillqqqqq
jjjjjppwww
stdout
138