結果

問題 No.866 レベルKの正方形
ユーザー TAISA_TAISA_
提出日時 2019-08-16 22:51:16
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
TLE  
実行時間 -
コード長 4,075 bytes
コンパイル時間 2,383 ms
コンパイル使用メモリ 184,136 KB
実行使用メモリ 89,164 KB
最終ジャッジ日時 2023-10-24 02:33:40
合計ジャッジ時間 10,664 ms
ジャッジサーバーID
(参考情報)
judge11 / judge13
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,372 KB
testcase_01 AC 2 ms
4,372 KB
testcase_02 AC 2 ms
4,372 KB
testcase_03 AC 2 ms
4,372 KB
testcase_04 AC 2 ms
4,372 KB
testcase_05 AC 2 ms
4,372 KB
testcase_06 AC 2 ms
4,372 KB
testcase_07 AC 2 ms
4,372 KB
testcase_08 TLE -
testcase_09 -- -
testcase_10 -- -
testcase_11 -- -
testcase_12 -- -
testcase_13 -- -
testcase_14 -- -
testcase_15 -- -
testcase_16 -- -
testcase_17 -- -
testcase_18 -- -
testcase_19 -- -
testcase_20 -- -
testcase_21 -- -
testcase_22 -- -
testcase_23 -- -
testcase_24 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
#define all(vec) vec.begin(), vec.end()
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
constexpr ll INF = (1LL << 30) - 1LL;
constexpr ll LINF = (1LL << 60) - 1LL;
constexpr double eps = 1e-9;
constexpr ll MOD = 1000000007LL;
template <typename T> bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
};
template <typename T> bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
};
template <typename T> ostream &operator<<(ostream &os, vector<T> v) {
    for (int i = 0; i < v.size(); i++) {
        os << v[i] << (i + 1 == v.size() ? "\n" : " ");
    }
    return os;
}
template <typename T> vector<T> make_v(size_t a) { return vector<T>(a); }
template <typename T, typename... Ts> auto make_v(size_t a, Ts... ts) {
    return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}
template <typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type fill_v(T &t, const V &v) {
    t = v;
}
template <typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type fill_v(T &t, const V &v) {
    for (auto &e : t) {
        fill_v(e, v);
    }
};
struct Segtree {
    int H, W;
    vector<vector<int>> dat;
    Segtree() {}
    void build(int H_, int W_, vector<vector<int>> &f) {
        H = 1;
        while (H < H_) {
            H <<= 1;
        }
        W = 1;
        while (W < W_) {
            W <<= 1;
        }
        dat.assign(2 * H - 1, vector<int>(2 * W - 1, 0));
        for (int i = 0; i < (int)f.size(); i++) {
            for (int j = 0; j < (int)f[0].size(); j++) {
                dat[i + H - 1][j + W - 1] = f[i][j];
            }
        }
        for (int i = 2 * H - 2; i > H - 2; i--) {
            for (int j = W - 2; j >= 0; j--) {
                dat[i][j] = dat[i][2 * j + 1] | dat[i][2 * j + 2];
            }
        }
        for (int i = H - 2; i >= 0; i--) {
            for (int j = 0; j < 2 * W - 1; j++) {
                dat[i][j] = dat[2 * i + 1][j] | dat[2 * i + 2][j];
            }
        }
    }
    int query(int li, int lj, int ri, int rj) { //(y1,x1),(y2,x2)
        return queryh(li, lj, ri, rj, 0, H, 0);
    }
    int queryh(int li, int lj, int ri, int rj, int si, int ti, int k) {
        if (ri <= si || ti <= li) {
            return 0;
        }
        if (li <= si && ti <= ri) {
            return queryw(lj, rj, 0, W, k, 0);
        }
        const int mi = (si + ti) / 2;
        return queryh(li, lj, ri, rj, si, mi, 2 * k + 1) |
               queryh(li, lj, ri, rj, mi, ti, 2 * k + 2);
    }
    int queryw(int lj, int rj, int sj, int tj, int i, int k) {
        if (rj <= sj || tj <= lj) {
            return 0;
        }
        if (lj <= sj && tj <= rj) {
            return dat[i][k];
        }
        const int mj = (sj + tj) / 2;
        return queryw(lj, rj, sj, mj, i, 2 * k + 1) |
               queryw(lj, rj, mj, tj, i, 2 * k + 2);
    }
};
int h, w, k;
Segtree seg;
inline int popcnt(int k) { return __builtin_popcount(k); }
int calc(int p) {
    int res = 0;
    for (int i = 1; i < h; i++) {
        int y = i, x = 0;
        int l = 0;
        while (x < w && y < h) {
            while (l <= x && popcnt(seg.query(i + l, l, y + 1, x + 1)) >= p) {
                l++;
            }
            res += l;
            x++;
            y++;
        }
    }
    for (int i = 0; i < w; i++) {
        int y = 0, x = i;
        int l = 0;
        while (x < w && y < h) {
            while (l <= y && popcnt(seg.query(l, i + l, y + 1, x + 1)) >= p) {
                l++;
            }
            res += l;
            x++;
            y++;
        }
    }
    return res;
}
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> h >> w >> k;
    auto a = make_v<int>(h, w);
    for (int i = 0; i < h; i++) {
        string s;
        cin >> s;
        for (int j = 0; j < w; j++) {
            a[i][j] = 1 << (s[j] - 'a');
        }
    }
    seg.build(h, w, a);
    cout << calc(k) - calc(k + 1) << endl;
}
0