結果
| 問題 |
No.866 レベルKの正方形
|
| コンテスト | |
| ユーザー |
qwewe
|
| 提出日時 | 2025-05-14 13:15:02 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
MLE
|
| 実行時間 | - |
| コード長 | 8,341 bytes |
| コンパイル時間 | 1,102 ms |
| コンパイル使用メモリ | 84,960 KB |
| 実行使用メモリ | 545,536 KB |
| 最終ジャッジ日時 | 2025-05-14 13:16:06 |
| 合計ジャッジ時間 | 10,024 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | -- * 3 |
| other | AC * 8 MLE * 1 -- * 13 |
ソースコード
#include <iostream>
#include <vector>
#include <string>
#include <numeric>
// Use long long for the answer count to avoid potential overflow, although unlikely given constraints.
using ll = long long;
// Precompute column prefix frequencies
// col_freq[j][i][c] will store the count of character with index c ('a' corresponds to 0, 'b' to 1, etc.)
// in column j (0-based index), covering rows from 0 to i-1 (0-based index).
std::vector<std::vector<std::vector<int>>> col_freq;
// Store the grid characters
std::vector<std::string> grid;
int H, W, K; // Grid dimensions and target distinct count K
// Helper function to update character counts and the distinct character count.
// It's used when incrementally building the first square S(i1, 0, s) for each row pair (i1, i2).
// `counts`: array storing frequency of each character 'a'-'z'.
// `distinct_count`: current number of distinct characters with count > 0.
// `char_idx`: index of the character (0-25) being updated.
// `delta`: change in count (+1 for adding, -1 for removing).
inline void update_counts(std::vector<int>& counts, int& distinct_count, int char_idx, int delta) {
// Store original count before modification
int original_count = counts[char_idx];
// Update count
counts[char_idx] += delta;
// Check if the distinct count needs to change based on transitions to/from zero count
// If the count was positive and becomes zero or less (should strictly be zero)
if (original_count > 0 && counts[char_idx] <= 0) {
distinct_count--; // A character type is now gone
}
// If the count was zero or less (should strictly be zero) and becomes positive
else if (original_count <= 0 && counts[char_idx] > 0) {
distinct_count++; // A new character type appeared
}
}
int main() {
// Use fast I/O operations
std::ios_base::sync_with_stdio(false);
std::cin.tie(NULL);
// Read input dimensions H, W, and target K
std::cin >> H >> W >> K;
// Read the grid characters
grid.resize(H);
for (int i = 0; i < H; ++i) {
std::cin >> grid[i];
}
// Initialize and compute column prefix frequencies
// Dimensions: W columns, H+1 rows (index 0 to H), 26 characters
col_freq.assign(W, std::vector<std::vector<int>>(H + 1, std::vector<int>(26, 0)));
for (int j = 0; j < W; ++j) { // Iterate through columns
for (int i = 1; i <= H; ++i) { // Iterate through rows (using 1-based index logic for prefix sums)
// Copy frequencies from the row above
for (int c = 0; c < 26; ++c) {
col_freq[j][i][c] = col_freq[j][i - 1][c];
}
// Increment the frequency for the character at grid[i-1][j]
// Need boundary check for grid access (i-1 >= 0 guaranteed by loop i=1..H)
if (i - 1 < H && j < W) { // grid is HxW, 0-indexed
col_freq[j][i][grid[i - 1][j] - 'a']++;
}
}
}
// Variable to store the total count of level K squares found
ll total_k_level_squares = 0;
// Iterate through all possible top rows `i1` (0-based index)
for (int i1 = 0; i1 < H; ++i1) {
// `counts_1`: Frequencies for the square starting at (i1, 0) with current side length s
std::vector<int> counts_1(26, 0);
// `distinct_1`: Distinct character count for the square S(i1, 0, s)
int distinct_1 = 0;
// Iterate through all possible bottom rows `i2` (0-based index), starting from `i1`
for (int i2 = i1; i2 < H; ++i2) {
// Calculate current side length `s`
int s = i2 - i1 + 1;
// If square width `s` exceeds grid width `W`, it's invalid. Break inner loop for `i2`.
if (s > W) break;
// Update `counts_1` and `distinct_1` incrementally for the square S(i1, 0, s)
// This update corresponds to expanding the square from size (s-1)x(s-1) to s x s.
// This happens when `i2` increments by 1, which also increments `s` by 1.
// The new cells added are in row `i2` (columns 0 to s-1) and column `s-1` (rows `i1` to `i2-1`).
// Add cells from the new row `i2`, columns 0 to `s-1`
for(int j = 0; j < s; ++j) {
if (i2 < H && j < W) { // Check grid bounds before access
int char_idx = grid[i2][j] - 'a';
update_counts(counts_1, distinct_1, char_idx, 1); // Add character
}
}
// Add cells from the new column `s-1`, rows `i1` to `i2-1`
int col_idx = s - 1; // column index is s-1 (0-based)
// Check if column index `col_idx` is valid
if (col_idx >= 0 && col_idx < W) {
for (int row = i1; row < i2; ++row) { // Iterate rows i1 to i2-1
if (row < H) { // Check row bounds
int char_idx = grid[row][col_idx] - 'a';
update_counts(counts_1, distinct_1, char_idx, 1); // Add character
}
}
}
// After the O(s) update, `counts_1` and `distinct_1` represent the square S(i1, 0, s).
// Check if this square (top-left at (i1, 0), side s) has K distinct characters.
if (distinct_1 == K) {
total_k_level_squares++;
}
// Now perform horizontal sliding window for squares starting at row `i1` with side `s`
// Copy the state of the first square S(i1, 0, s) to use for sliding
std::vector<int> current_counts = counts_1;
int current_distinct = distinct_1;
// Slide the window horizontally. The loop variable `j1` represents the starting column index (0-based).
// We slide from column 1 up to W-s.
for (int j1 = 1; j1 <= W - s; ++j1) {
// Update state from square S(i1, j1-1, s) to S(i1, j1, s)
// This involves removing column `j1-1` and adding column `j1+s-1`.
// The rows involved in these columns are `i1` to `i2`.
int remove_col_idx = j1 - 1;
int add_col_idx = j1 + s - 1;
// Defensive check for column indices validity although loop bounds should ensure this
if (remove_col_idx < 0 || remove_col_idx >= W || add_col_idx < 0 || add_col_idx >=W) {
continue;
}
// Update using column prefix sums. Takes O(alpha) = O(26) time.
for (int c_idx = 0; c_idx < 26; ++c_idx) {
// Calculate count of char `c_idx` in the column segment to remove
// Rows `i1` to `i2` (0-based) correspond to prefix sum range `[i1, i2+1)`
int to_remove = col_freq[remove_col_idx][i2 + 1][c_idx] - col_freq[remove_col_idx][i1][c_idx];
// Calculate count of char `c_idx` in the column segment to add
int to_add = col_freq[add_col_idx][i2 + 1][c_idx] - col_freq[add_col_idx][i1][c_idx];
// Store original count before modifying `current_counts`
int original_count = current_counts[c_idx];
// Calculate the final count after remove and add operations
int final_count = original_count - to_remove + to_add;
// Update the count array
current_counts[c_idx] = final_count;
// Check if the distinct count changes based on transitions to/from zero count
if (original_count > 0 && final_count <= 0) { // Character type disappeared
current_distinct--;
} else if (original_count <= 0 && final_count > 0) { // New character type appeared
current_distinct++;
}
}
// Check if the new square S(i1, j1, s) has K distinct characters
if (current_distinct == K) {
total_k_level_squares++;
}
}
}
}
// Print the final total count
std::cout << total_k_level_squares << std::endl;
return 0;
}
qwewe