Language: C++

#include <iostream>
#include <vector>
using namespace std;

long long sum[2100][2100];

int check(int i, int j, const vector<string> &fi) {
    int n = (int)fi.size();
    int m = (int)fi[0].size();
    if (i < 0 || i >= n || j < 0 || j >= m) return 0;
    if (fi[i][j] == '#') return 1;
    else return 0;
}

long long solve(vector<string> fi) {
    // sum[a][b] := マス (i, j) であって i+j = a, i <= b を満たす範囲内にある黒マスの個数 (斜め累積和)
    memset(sum, 0, sizeof(sum));
    int n = (int)fi.size();
    int m = (int)fi[0].size();
    for (int ij = 0; ij < n+m-1; ++ij) {
        sum[ij][0] = 0;
        for (int i = 0; i < (n+m)*3; ++i) {
            int j = ij - i;
            int add = 0;
            if (i >= 0 && i < n && j >= 0 && j < m && fi[i][j] == '#') add = 1;
            sum[ij][i+1] = sum[ij][i] + add;
        }
    }
    
    long long res = 0;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (fi[i][j] != '#') continue;
            for (int k = 1; k < n+m; ++k) {
                int i2 = i + k;
                int j2 = j - k;
                if (i2 < 0 || i2 >= n || j2 < 0 || j2 >= m) continue;
                if (fi[i2][j2] != '#') continue;
                
                // 対辺が左上方向にあるもの
                {
                    int ij = i+j - k*2;
                    if (ij >= 0) {
                        if (check(i-k, j-k, fi)) ++res; // 直角二等辺三角形
                        if (check(i, j-k*2, fi)) ++res; // 直角二等辺三角形
                        
                        int a = max(i-k+1, 0);
                        int b = max(i, 0);
                        if (a <= b) res += (sum[ij][b] - sum[ij][a]) * 2; // それ以外
                    }
                }
                
                // 対辺が右下方向にあるもの
                {
                    int ij = i+j + k*2;
                    if (ij <= n+m-2) {
                        if (check(i+k, j+k, fi)) ++res; // 直角二等辺三角形
                        if (check(i+k*2, j, fi)) ++res; // 直角二等辺三角形
                        
                        int a = i+k+1;
                        int b = i+k*2;
                        res += (sum[ij][b] - sum[ij][a]) * 2; // それ以外
                    }
                }
            }
        }
    }
    return res;
}

int main() {
    int H, W;
    cin >> H >> W;
    vector<string> input(H);
    for (int i = 0; i < H; ++i) cin >> input[i];
        
    long long res = 0;
    res += solve(input);

    // 盤面を左右反転
    for (int i = 0; i < H; ++i) reverse(input[i].begin(), input[i].end());
    res += solve(input);
        
    cout << res / 2 << endl;
}
















Compiler output:
a.cc: In function 'long long int solve(std::vector<std::__cxx11::basic_string<char> >)':
a.cc:17:5: error: 'memset' was not declared in this scope
   17 |     memset(sum, 0, sizeof(sum));
      |     ^~~~~~
a.cc:3:1: note: 'memset' is defined in header '<cstring>'; this is probably fixable by adding '#include <cstring>'
    2 | #include <vector>
  +++ |+#include <cstring>
    3 | using namespace std;
a.cc: In function 'int main()':
a.cc:81:33: error: 'reverse' was not declared in this scope
   81 |     for (int i = 0; i < H; ++i) reverse(input[i].begin(), input[i].end());
      |                                 ^~~~~~~