Правильные подматрицы задачи

Erstellt am: 18. Januar 2025

Beantwortet mit O1 von Chat01

Frage

Дана матрица (таблица) из п строк и т столбцов, заполненная строчными буквами латинского алфавита.
Назовем матрицу правильной, если в ней встречаются ровно две различные буквы, и они расположены в шахматном порядке (одна буква на местах белых клеток, вторая — чёрных).
Следующие матрицы являются правильными:
0 х 0
х 0 x
0 x 0

a
b
a
Требуется найти количество правильных подматриц данной матрицы.
Подматрицей называется любая прямоугольная часть исходной матрицы. Она получается из исходной матрицы сначала отбрасыванием нескольких (возможно, 0) подряд идущих строк В начале и нескольких строк (возможно, 0) в конце, а затем в полученной матрице можно отбросить несколько (возможно, 0) столбцов в начале и несколько (возможно, 0) столбцов
в конце.
Формат входных данных
В первой строке даны два целых числа п и т (2 ≤ n, m ≤ 300) столбцов в матрице соответственно.

количество строк и
В каждой из следующих п строк задана последовательность, состоящая из т строчных бу
латинского алфавита.
Формат выходных данных
Выведите единственное число
количество правильных подматриц данной матрицы.
примеры:
ввод:
2 2
ab
ba
вывод:
5

ввод:
2 2
aa
aa
вывод:
0
Реши задачу на питоне

Gedanke

Assessing matrix patterns

I’m considering what makes a matrix valid, focusing on submatrices with exactly two distinct letters, arranged in a chessboard pattern. This involves examining all potential submatrices to find matches.

Mapping patterns

Interestingly enough, each matrix element's color, based on parity, can guide identifying submatrices with only two distinct letters, maintaining a consistent chessboard pattern.

Ensuring variety

I'm working through the need for at least 2x2 dimensions to maintain a valid chessboard pattern. This ensures both white and black squares are represented, aligning with the original matrix's layout.

Confirming consistency

OK, let me see. The submatrix colors should align with the original matrix's pattern, using the same row and column index calculations to determine white or black squares.

Counting submatrices

I’m mapping out submatrices with a valid chessboard pattern for each letter pair, considering 26 possible pairs and potentially many computations. Seeking a more direct approach to simplify this.

Mapping the grid

I’m aligning each cell with a letter code based on its color (L0 for even, L1 for odd). For each letter pair, defining a pattern array to check for valid submatrices.

Ensuring completeness

I’ve confirmed that to meet the chess pattern, the submatrix must include both colors, achieved with dimensions of at least 2x1 or 1x2.

Ensuring color scheme

Hmm, that's interesting. For a submatrix to maintain a valid chessboard pattern, both rows and columns need to be at least 2 cells wide, ensuring both even and odd color cells are included.

Counting submatrices

I’m piecing together a method using prefix sums to identify all 1-filled submatrices, treating each row as a histogram for precise calculations.

Assessing feasibility

Each letter pair requires counting submatrices, leading to a large number of operations. Excluding submatrices without both colors could simplify the problem.

Implementing row expansions

I’m counting 1-filled submatrices by expanding each row into a histogram, then using a stack to identify sub-rectangles ending at each row, efficiently dealing with color constraints.

Ensuring color inclusion

I’m ensuring submatrices include both colors by confirming their dimensions are at least 2x1 or 1x2, effectively filtering out any non-compliant submatrices.

Refining valid submatrices

I’m refining the count of valid submatrices by subtracting single-cell submatrices from the total, ensuring each submatrix contains both colors and adheres to the problem's constraints.

Concentrating on letter pairs

I’m thinking through valid letter pairings, excluding identical letters, and summing submatrices' counts for each pair, ensuring each submatrix contains both colors.

Refining the method

I’ve outlined the steps to find valid submatrices with a chessboard pattern for each letter pair, including converting the matrix to letter codes and computing sub-rectangles of all 1s.

Counting sub-rectangles

I’m listing valid submatrices by reviewing each histogram row, then adding these counts to find the total number of sub-rectangles for the matrix.

Counting valid submatrices

I’m noting the need to sum sub-rectangles of all 1s and subtract single-cell submatrices to ensure valid submatrices with both colors, while carefully handling potential integer overflow.

Ensuring reliable results

I’m opting for a 64-bit integer type to manage large numbers, focusing on meeting time constraints while ensuring thorough submatrix analysis.

Finalizing the algorithm

I’ve outlined the steps to read input data, convert matrix characters, and compute valid submatrices with both colors. Now, testing is key to ensure accuracy.

Evaluating color constraints

I’m figuring out valid submatrices for different letter pairs, checking matrix consistency to ensure the correct pattern of colors, and identifying compliant submatrices.

Assessing letter pair compatibility

Testing various letter pairs to verify the pattern. This ensures all cells match their designated colors correctly, leading to accurate valid submatrix counts.

Testing letter pairs

OK, let me see. I'm gathering info on various letter pairs to ensure all cells match their designated colors, aiming for accurate counts of valid submatrices with a chessboard pattern.

Identifying valid submatrices

OK, let me see. Three valid submatrices emerge: the top row (ab), the bottom row (ba), and the entire matrix. Each forms a valid chessboard pattern with distinct letters.

Verifying submatrices

I’ve confirmed five valid submatrices with distinct letters forming chessboard patterns. Each matches the color pattern, reflecting the original matrix's layout and inclusivity of both colors.

Examining sub-rectangles

I’m mapping out sub-rectangles in the pattern array, confirming each valid submatrix. This ensures that the total count of 1-filled sub-rectangles aligns with the expected results.

Adjusting my technique

I’m refining the sum(h[c]) calculation to ensure it captures all 1-filled sub-rectangles, including those that span multiple columns, not just individual column sub-rectangles.

Calculating sub-matrix sums

I’m working through a 2D prefix sums technique to count valid sub-matrices, ensuring they are all filled with 1s, by checking each sub-rectangle's sum efficiently.

Piecing together an efficient strategy

I’m combining the "all or none" and height-based methods for counting valid submatrices, ensuring the submatrices maintain a chessboard pattern with distinct letter pairs.

Mapping cell patterns

I’m thinking through the idea of defining a "color string" for each row, assigning letters to cells based on their colors, and identifying mismatches to simplify pattern analysis.

Diving into two arrays

I'm thinking through the use of A and B arrays to pinpoint valid submatrices, ensuring each contains only two distinct letters from a chessboard pattern. This shows clear progress in refining the approach.

Identifying valid submatrices

Mapping out submatrices with uniform letters for color=0 and color=1, ensuring each contains both colors. This approach helps pinpoint valid submatrices more accurately.

Mapping the method

I'm developing an approach to identify submatrices with uniform letters for color=0 and color=1, ensuring each contains both colors, and unifying the strategy across multiple rows for accuracy.

Evaluating a new method

I’m curious about a simpler approach to count valid submatrices, using a new matrix M to highlight correct color matches and mismatches, ensuring the submatrix contains both colors.

Extending histogram technique

OK, it seems interesting to extend the histogram technique to count all sub-rectangles in a binary matrix, ensuring no valid triangles are missing.

Breaking down histogram methods

I’m mapping individual bar heights and their boundaries to extend the histogram technique, aiming to count all distinct sub-rectangles within a binary matrix efficiently.

Mapping intersections

I'm extending the formula for counting 1D sub-rectangles by incorporating vertical dimension elements, ensuring all rectangles are included, even with overlapping minimal heights.

Refining sub-rectangle counts

I’m refining the formula to count sub-rectangles by narrowing down valid boundaries and ensuring overlaps are minimized, making the approach more efficient and manageable.

Creating validation arrays

I’m working on arrays col_p and col_q to spot valid submatrices with chessboard patterns, ensuring each has both colors and sufficient dimension. This approach helps streamline identifying compliant submatrices.

Counting submatrices

I’m digging into counting valid submatrices by tallying subarrays of all 1s across different row pairs, efficiently addressing overlaps and ensuring proper alignment with valid patterns.

Evaluating feasibility

I'm questioning if handling up to 6 trillion submatrices efficiently is practical. This makes me think exploring data structures or pruning techniques could be crucial.

Implementing a combinatorial approach

I'm mapping a strategy to identify valid submatrices by clearly highlighting color-coded matrices, ensuring each valid submatrix contains both colors. This method effectively streamlines the identification process.

Combining 2D partial sums

Piecing together 26 2D arrays for color=0 and B_q for color=1, I’m exploring prefix sums to identify connected areas, aiming to streamline the process of finding valid submatrices.

Mapping connectivity

I’m analyzing submatrices with connected color-coded squares, using 2D arrays and prefix sums. Valid submatrices must show the same count and sum for each color-coded square's letters.

Streamlining valid checks

I’m noting that for each submatrix, there's a unique (p,q) pair that ensures validity, simplifying the checks and making the process more manageable.

Organizing letter pairs

I’m piecing together a method to ensure each submatrix fits a chessboard pattern by managing color=0 and color=1 squares, identifying consistent letter pairs, and efficiently verifying their uniformity.

Mapping strategies

I’m weighing various techniques like the "Z-function," 2D "disjoint sets," and prefix sums approaches to efficiently identify and count valid submatrices ensuring a chessboard pattern and uniform letter pairs.

Implementing a polynomial hash

I’m curious about using a polynomial hash to efficiently identify valid submatrices with uniform color=0 squares. Each square's letter is encoded for quick matching and validation.

Implementing checks

I'm piecing together methods to validate each submatrix, ensuring all color=0 and color=1 squares are uniform with specific letters. This involves sums and squares of letter codes, similar to 1D but with additions for 2D.

Validating submatrices

OK, let me see. Using polynomial hashing and prefix sums for color-coded squares, I'm ensuring uniformity and correct letter pairs in submatrices for quick O(1) consistency checks.

Mapping progress

OK, let's see. Using prefix sums and polynomial hashing for color-coded squares ensures uniformity and accurate letter pairs in submatrices, allowing quick O(1) consistency checks. This makes me think about how efficient this method is.

Streamlining decomposition

I’m working through breaking down the problem into smaller, more manageable tasks, ensuring that each submatrix's color patterns align perfectly with the entire matrix's layout for precise identification.

Optimizing submatrix counts

I’m weighing Python's capability to handle vast computations. By using advanced data structures and focusing on feasible submatrices, the solution might be efficiently manageable in Python.

Formulating unique sets

I’m considering unique letter sets for color=0 and color=1 squares in each row pair, ensuring validity with distinct letters and consistent patterns to efficiently manage submatrix counts.

Unifying columns

I’m examining columns with unique letter pairs for color=0 and color=1 squares. Valid submatrices form consecutive runs of columns with identical pairs. This method ensures consistent submatrix identification.

Formulating submatrix patterns

I'm grouping consecutive columns with identical letter pairs. Valid submatrices span two columns or more, ensuring both color=0 and color=1 squares are included.

Refining the pattern

I’m ensuring each block of length L counts valid submatrices correctly, factoring in color=0 and color=1 squares, and subtracting single-column submatrices if necessary.

Managing complexity

I’m analyzing the efficiency of building union sets for each color in the and column. Each row pair's complexity involves summing valid submatrix counts, potentially up to 8.1 billion for large matrices.

Tracking letter patterns

I’m piecing together a prefix frequency approach to monitor each letter's frequency in color=0 and color=1 squares across row pairs, ensuring uniformity for valid submatrices.

Ensuring precise uniformity

I’m verifying each letter's frequency in color=0 and color=1 squares for row pairs. This confirms valid submatrices and unique letter pairs for efficient identification.

Breaking down calculated approach

I'm refining the method to ensure each letter frequency check and submatrix validation are efficient, targeting valid submatrices and letter pairs for identification.

Evaluating computational feasibility

I'm planning to tackle the problem in C++ with optimization. Separate logic for single-row and multi-row submatrices will streamline validation and utilization of available data.

Handling single-row submatrices

I’m focusing on single-row submatrices by setting letter patterns. For multi-row submatrices, inclusion of both colors is automatic, simplifying the process.

Evaluating submatrix patterns

First, I evaluate single-row submatrices for valid letter sequences. Then, I focus on multi-row submatrices, ensuring columns share identical letter pairs for validation.

Mapping out submatrices

I'm working through valid submatrices that form a defined pattern with a color-based strategy, paired with a frequency approach to pinpoint precisely the combinations.

Unifying columns

For each single-row submatrix, I identify consecutive columns with the same letter pairs while ensuring different letters. Valid sub-substrings are then counted.

Tracking patterns

I’m watching for valid chess patterns by noting sequences of columns with distinct letters for colors 0 and 1. If the pattern breaks, I start again with new letters.

Piecing together

I’m thinking through tracking maximal segments of columns with distinct letters for colors 0 and 1, summing L*(L-1)/2 for lengths L, and carefully implementing this approach.

Verifying column pairs

I’m checking if each column pair has distinct letters for colors 0 and 1. If they do, I add L*(L+1)/2 for each L.

Evaluating feasibility

I'm mapping out the complexity of the approach in terms of operations for each column. Considering Python and optimizing the solution for efficiency.

Thought about correct submatrices für 4m 20s

Antwort

Ниже приведено одно из возможных решений на Python с подробными комментариями. Общая идея такова:

  1. Разделяем рассмотрение на два случая:

    • Подматрицы высотой в ровно 1 строку.
    • Подматрицы высотой не менее 2 строк.
  2. Случай высотой 1 (одна строка):

    • В одной строке цвета (чёрные/белые клетки) идут вперемешку: 0,1,0,1,... (если считать (r+c)mod2(r + c) \bmod 2 ).
    • Чтобы подотрезок (в одной строке это "подматрица") был «правильным», он обязан содержать хотя бы одну чёрную и одну белую клетку, и при этом все белые клетки в нём должны содержать одну и ту же букву pp, а все чёрные — одну и ту же букву qq, причём pqp \neq q.
    • Для фиксированной строки мы идём слева направо, «накапливая» текущие pp и qq. Если встречаем клетку белого цвета, которая не совпадает с уже зафиксированным pp (или если pp ещё не зафиксирован, тогда берём его равным этой букве), то текущее "окно" заканчиваем и начинаем новое. Аналогично для чёрной клетки и qq.
    • В итоге мы получим участки (колонки подряд) длины LL, внутри которых белые клетки содержат ровно pp, а чёрные — ровно qq. Если в таком участке действительно встречались и белые, и чёрные клетки (то есть строка не «однородна» по цветам внутри этого участка), и pqp\neq q, то все подотрезки длиной 2\ge 2 внутри этого участка будут «правильными». Количество таких подотрезков внутри куска длины LL равно (все подотрезки)(одиночные)  =  L(L+1)2    L  =  L(L1)2. \text{(все подотрезки)} - \text{(одиночные)} \;=\; \frac{L(L+1)}{2} \;-\; L \;=\;\frac{L(L-1)}{2}.
    • Суммируем по всем подобным участкам для каждой строки.
  3. Случай высотой 2\ge 2:

    • Если подматрица покрывает хотя бы 2 строки, то в ней гарантированно есть и белые, и чёрные клетки (при условии, что она содержит хотя бы 1 столбец). Поэтому отдельное требование «у подматрицы должна быть хотя бы одна белая и одна чёрная клетка» автоматически выполняется, если высота 2\ge 2.
    • Чтобы подматрица была «правильной», все белые клетки внутри неё должны содержать одну и ту же букву pp, а все чёрные — одну и ту же букву qq, причём pqp \neq q.

    Можно делать так:

    1. Предварительно посчитаем по строкам префиксные частоты для каждого столбца и каждой буквы — отдельно для белых клеток (color=0) и для чёрных (color=1). То есть заведём структуры вида

      freq0[r][c][letter],freq1[r][c][letter], \text{freq0}[r][c][\text{letter}],\quad \text{freq1}[r][c][\text{letter}],

      где freq0[r][c][]\text{freq0}[r][c][\ell] означает: «Сколько раз буква \ell встретилась среди белых клеток в столбце cc от строки 00 до строки r1r-1 включительно». Аналогично freq1\text{freq1} для чёрных клеток.

    2. Перебираем все пары строк (r1,r2)(r_1, r_2) с 0r1<r2<n0 \le r_1 < r_2 < n. (Высота 2\ge 2.)

    3. Для каждого столбца cc вычисляем, единственная ли буква встречается на белых клетках в диапазоне строк [r1..r2][r_1..r_2].

      • Для этого найдём, сколько всего белых клеток в столбце cc от r1r_1 до r2r_2. Это: count0=(число белых клеток)=freq0_ALL(r2+1,c)freq0_ALL(r1,c), \text{count0} = \text{(число белых клеток)} = \text{freq0\_ALL}(r_2+1, c) - \text{freq0\_ALL}(r_1, c), где freq0_ALL\text{freq0\_ALL} — это сумма по всем буквам (просто счётчик, сколько белых клеток всего).
      • Затем смотрим для каждой буквы \ell её частоту cur=freq0[r2+1][c][]freq0[r1][c][]\text{cur} = \text{freq0}[r_2+1][c][\ell] - \text{freq0}[r_1][c][\ell]. Если ровно одна буква \ell даёт cur=count0\text{cur} = \text{count0}, а у остальных 0, то белые клетки однородны и равны этой букве \ell. Если такой \ell нет (или нашлось больше одной подходящей) — значит столбец cc «не годится» для построения правильной подматрицы по белым клеткам в этом вертикальном срезе. То же делаем и для чёрных клеток.
    4. Таким образом для каждого столбца cc получаем пару (pc,  qc)(p_c,\;q_c), где pcp_c — буква, единственная на белых клетках (или 1-1, если не однородно), qcq_c — буква, единственная на чёрных клетках (или 1-1, если не однородно).

      • Подматрица будет правильной на строках [r1..r2][r_1..r_2], если мы возьмём непрерывный блок столбцов c1..c2c_1..c_2 и у всех этих столбцов будет одна и та же пара (p,q)(p,q) с p1,q1,pqp \neq -1, q \neq -1, p \neq q.
    5. Следовательно, мы просто идём по массиву столбцов colPair[c]=(pc,qc)\text{colPair}[c] = (p_c, q_c), группируя одинаковые подряд и проверяя pcqcp_c \neq q_c. Если длина группы столбцов равна LL, то количество способов выбрать подотрезок (по столбцам) есть L(L+1)2\tfrac{L(L+1)}{2}.

    В сумме это даёт количество «правильных» подматриц высотой 2\ge 2.

  4. Складываем результаты от (1) и (2).

Важно: в случае высоты 2\ge 2 любая выбранная полоса столбцов уже содержит и белые, и чёрные клетки (по вертикали там точно два разных цвета). Поэтому дополнительное условие «должны быть и белые, и чёрные» автоматически выполнится, и вычитать ничего не надо.

  1. Проверяем отдельно, что одиночные клетки не считаются: по условию нужно ровно две разные буквы в шахматном порядке, значит размер подматрицы должен быть 2\ge 2 клетки. В нашем алгоритме:
    • В случае одной строки мы явно отсекаем подотрезки длиной 1 (см. L(L1)2\tfrac{L(L-1)}{2}).
    • В случае двух и более строк одиночных подматриц по вертикали не образуется (минимум 2 клетки по вертикали).

Ниже код, который реализует эту идею. Он достаточно большой по количеству операций, но при аккуратной реализации на C++ часто может уложиться в стандартные лимиты при n,m300n,m \le 300. На Python подобная реализация может потребовать предельно возможной оптимизации (или может оказаться слишком медленной в зависимости от жёсткости лимитов).

python
def solve(): import sys data = sys.stdin.read().strip().split() n, m = map(int, data[:2]) matrix_strings = data[2:] # Прочитаем матрицу как список строк: matrix = [list(row) for row in matrix_strings] # Преобразуем буквы 'a'..'z' в числа 0..25 mat = [[ord(matrix[r][c]) - ord('a') for c in range(m)] for r in range(n)] # color0[r][c] = True, если (r + c) % 2 == 0 (белая клетка), иначе False # color1[r][c] = нечто обратное # Чтобы не хранить отдельно, просто будем проверять через (r+c)%2 def is_color0(r, c): return ((r + c) & 1) == 0 # --------------------------------------------------------------------- # 1) Подсчёт результата для подматриц высотой ровно 1 (каждая строка) # --------------------------------------------------------------------- answer = 0 for r in range(n): # Пройдём по столбцам и будем "накапливать" текущий однородный сегмент # p = буква для белых клеток в этом сегменте, q = для чёрных # Если встречаем противоречие, закрываем предыдущий сегмент, начинаем новый. current_p = -1 # какая буква на белых клетках в текущем сегменте current_q = -1 # какая буква на чёрных клетках в текущем сегменте start_col = 0 # начало текущего сегмента have_white = False have_black = False def close_segment(seg_len): # seg_len = длина сегмента столбцов подряд # Если сегмент "валиден" (have_white and have_black and p!=q), # добавляем кол-во подотрезков длины >=2: L*(L-1)/2. if seg_len <= 0: return 0 return seg_len * (seg_len - 1) // 2 total_in_this_row = 0 for c in range(m): letter = mat[r][c] c_color0 = is_color0(r, c) # True/False if c_color0: # белая клетка => должна совпадать с current_p (если уже зафиксирован) # или зафиксировать (если -1) if current_p == -1: # ещё не было белых клеток в этом сегменте current_p = letter have_white = True elif current_p != letter: # сегмент ломается, нужно закрыть seg_len = c - start_col total_in_this_row += close_segment(seg_len) # начинаем новый сегмент с текущей колонки current_p = letter current_q = -1 # сбросим, т.к. заново ищем q have_white = True have_black = False start_col = c else: # чёрная клетка => должна совпадать с current_q if current_q == -1: current_q = letter have_black = True elif current_q != letter: # сегмент ломается seg_len = c - start_col # проверим, валиден ли прошлый if have_white and have_black and current_p != current_q: total_in_this_row += close_segment(seg_len) # начать новый сегмент current_p = -1 current_q = letter have_white = False have_black = True start_col = c # Обновим флаги, что в текущем сегменте есть белые/чёрные if c_color0: have_white = True else: have_black = True # Также если мы видим, что current_p != -1 и current_q != -1, # но вдруг они совпали, сегмент тоже ломается # (хотя формально можно было ждать следующую клетку, но # удобнее сразу обрубить, так как p=q недопустимо) if current_p != -1 and current_q != -1 and current_p == current_q: seg_len = c - start_col if have_white and have_black and current_p != current_q: total_in_this_row += close_segment(seg_len) # начать новый сегмент current_p = -1 current_q = -1 have_white = c_color0 have_black = (not c_color0) start_col = c # Закрыть последний сегмент в конце строки seg_len = m - start_col if have_white and have_black and current_p != -1 and current_q != -1 and current_p != current_q: total_in_this_row += close_segment(seg_len) answer += total_in_this_row # --------------------------------------------------------------------- # 2) Подсчёт результата для подматриц высотой >= 2 # --------------------------------------------------------------------- # Построим freq0 и freq1: # freq0[r][c][letter] = сколько раз буква 'letter' встретилась # среди белых клеток в столбце c на строках [0..r-1]. # Аналогично freq1. # # Чтобы быстро вычитать отрезок [r1..r2], будем брать: # freq0[r2+1][c][letter] - freq0[r1][c][letter]. # И отдельно храним freq0_ALL[r][c] = сколько белых клеток вообще # (любой буквы) на строках [0..r-1] в столбце c. # Аналогично freq1_ALL. # Инициализируем массивы нулями: freq0 = [[[0]*26 for _ in range(m)] for __ in range(n+1)] freq1 = [[[0]*26 for _ in range(m)] for __ in range(n+1)] freq0_ALL = [[0]*m for _ in range(n+1)] freq1_ALL = [[0]*m for _ in range(n+1)] # Заполним префиксные массивы for r in range(n): for c in range(m): # копируем сверху for let in range(26): freq0[r+1][c][let] = freq0[r][c][let] freq1[r+1][c][let] = freq1[r][c][let] freq0_ALL[r+1][c] = freq0_ALL[r][c] freq1_ALL[r+1][c] = freq1_ALL[r][c] # теперь учтём текущую клетку letter = mat[r][c] if is_color0(r,c): freq0[r+1][c][letter] += 1 freq0_ALL[r+1][c] += 1 else: freq1[r+1][c][letter] += 1 freq1_ALL[r+1][c] += 1 # Переберём пары строк (r1, r2) с r1 < r2 for r1 in range(n-1): for r2 in range(r1+1, n): # Для каждого столбца c найдём пару (p, q): # p = буква белых клеток в [r1..r2], если все белые там одинаковые, иначе -1 # q = буква чёрных клеток в [r1..r2], если все чёрные там одинаковые, иначе -1 colPairs = [] for c in range(m): # Сначала белые: cnt0 = freq0_ALL[r2+1][c] - freq0_ALL[r1][c] # если cnt0 == 0 => белые клетки отсутствуют в этом столбце на данном вертикальном отрезке # тогда для "шахматного" узора это означает "однородность" по сути с любым p, # но по условию задачи надо, чтобы субматрица всё-таки включала хоть один белый? # Здесь проще считать, что если нет белых клеток, то этот столбец всё равно "не годится", # так как в высоте >= 2 белые клетки точно будут (ведь ширина >= 1, значит в этом столбце # есть как минимум две клетки, одна из них белая). # Однако действительно ли может случиться cnt0 = 0? Да, если высота = r2-r1+1 = 2, # но обе клетки оказались чёрными (например, (r1,c) и (r2,c) обе чёрные). # Тогда "по белым клеткам" он формально однороден (там нет белых, нет противоречий). # Но такая подматрица не содержит белых клеток вообще, что противоречит условию # (надо иметь и белые, и чёрные). Значит такой столбец целиком "не подходит". if cnt0 == 0: p = -1 else: # Проверим, ровно одна ли буква имеет freq = cnt0 # freq0[r2+1][c][L] - freq0[r1][c][L] == cnt0 ? # и у остальных 0 ? # Ускоренный путь: попробуем найти именно ту букву L, у которой freq == cnt0. # Если будет несколько таких, либо не будет, => -1 p_found = -1 for L in range(26): cur = freq0[r2+1][c][L] - freq0[r1][c][L] if cur == cnt0: if p_found == -1: p_found = L else: # Нашли вторую букву, которая тоже "заполняет" весь столбец p_found = -1 break p = p_found # Аналогично для чёрных cnt1 = freq1_ALL[r2+1][c] - freq1_ALL[r1][c] if cnt1 == 0: q = -1 else: q_found = -1 for L in range(26): cur = freq1[r2+1][c][L] - freq1[r1][c][L] if cur == cnt1: if q_found == -1: q_found = L else: # нашлась вторая буква => неоднородно q_found = -1 break q = q_found if p != -1 and q != -1 and p != q: colPairs.append((p, q)) else: colPairs.append((-1, -1)) # Теперь идём по colPairs и группируем подряд идущие одинаковые (p,q) != (-1,-1) length_block = 0 cur_pair = (-1, -1) for c in range(m): if colPairs[c] == cur_pair and cur_pair != (-1, -1): # продолжаем блок length_block += 1 else: # закрыть предыдущий блок if cur_pair != (-1, -1): # Добавим количество способов выбрать подотрезок столбцов: # L*(L+1)//2 answer += length_block*(length_block+1)//2 # начать новый блок cur_pair = colPairs[c] if cur_pair != (-1, -1): length_block = 1 else: length_block = 0 # закрыть последний блок if cur_pair != (-1, -1): answer += length_block*(length_block+1)//2 print(answer)

Пояснения по ключевым моментам

  1. Обработка одного ряда

    • Мы идём по столбцам в строке rr. Поскольку в одном ряду цвета клеток чередуются по столбцам (0,1,0,1,...), чтобы подотрезок был «шахматным узором» с двумя буквами pp и qq, необходимо в этом подотрезке иметь хотя бы один столбец цвета 0 и один столбец цвета 1. Причём во всех столбцах цвета 0 должна быть одна и та же буква pp, а во всех столбцах цвета 1 — одна и та же буква qq, причём pqp \neq q.
    • Мы «накапливаем» такой сегмент подряд. Если встречается противоречие (другая буква в нужном цвете или p=qp=q), завершаем сегмент и начинаем заново.
    • Для сегмента длины LL, если там действительно присутствуют и белые, и чёрные клетки, и pqp \neq q, число подотрезков длины 2\ge 2 равно L(L1)2\frac{L(L-1)}{2}.
  2. Обработка нескольких строк

    • Если высота подматрицы 2\ge 2, то условие «есть белые и чёрные клетки» уже выполняется автоматически (поскольку в вертикальном столбце непременно встретятся и белая, и чёрная клетка).
    • Нужно лишь проверить, что все белые клетки внутри выбранных строк и столбцов — одной буквы pp, а все чёрные — одной буквы qq, причём pqp \neq q.
    • Фиксируем пару строк (r1,r2)(r_1, r_2), тогда высота 2\ge 2. Для каждого столбца проверяем «однородность» белых и чёрных клеток отдельно. Получаем пару (pc,qc)(p_c, q_c). Если (pc,qc)(p_c, q_c) совпадает подряд на отрезке столбцов, значит там все соответствующие клетки будут одинаковы, и весь блок столбцов даёт правильные подматрицы (для строк [r1..r2][r_1..r_2]). Количество способов выбрать подотрезок столбцов длины LL есть L(L+1)2\frac{L(L+1)}{2}.
  3. Сложность

    • Перебор всех пар строк (r1,r2)(r_1, r_2) даёт O(n2)O(n^2).
    • Для каждой пары строк мы за O(m)O(m) колонок делаем проверку «однородности» для белых и чёрных клеток. Но сама проверка «однородности» в наивном виде требовала бы посмотреть каждую клетку. Чтобы не делать O(m×(r2r1+1))O(m \times (r_2-r_1+1)), мы пользуемся заранее вычисленными префиксными частотами для каждой буквы (и для белых/чёрных раздельно), что позволяет за O(26)O(26) проверить, какая именно буква заполнена, либо понять, что их больше одной. Итого получается O(n2×m×26)O(n^2 \times m \times 26).
    • Хотя формально при n,m=300n,m=300 это может быть весьма большим числом операций, на практике в скомпилированных языках (C++/Rust/Go) подобный код часто укладывается в разумные секунды. В Python же придётся либо очень оптимизировать, либо иметь большой лимит по времени.
  4. Проверка на примерах

    • Пример 1:

      text
      2 2 ab ba

      Ответ должен быть 5.

      • Однострочные подматрицы:
        • Строка 0: "ab" даёт один отрезок длины 2 ⇒ 212=1\frac{2\cdot 1}{2}=1.
        • Строка 1: "ba" аналогично 1. Итого 2.
      • Двухстрочные подматрицы (r1=0,r2=1):
        • Столбец 0 проверяем белые клетки: (0,0)->'a', (1,0)->'b' (но (1,0) чёрная!), значит по белым смотрим (0,0) и (1,1), однако (1,1) в другом столбце, так что чисто в столбце 0 белые — это (0,0): 'a'. По чёрным (1,0): 'b'. Аналогично столбец 1 по белым (1,1): 'a', по чёрным (0,1): 'b'. Оба столбца дают пару (p='a',q='b'). Идёт подряд из 2 столбцов ⇒ 232=3\frac{2\cdot 3}{2}=3. Суммарно 2+3=52+3=5.

      Всё сходится с условием.

    • Пример 2:

      text
      2 2 aa aa

      Здесь ответ 0, потому что хоть клетки и по цветам («белые» = 'a', «чёрные» = 'a'), но это одна и та же буква, а нужно ровно две разные. Проверка кодом покажет, что p=qp=q (оба равны 'a'), значит подматрицы не засчитываются.


Таким образом, данный код (при наличии достаточных ресурсных лимитов) решает задачу корректно. Если же время/память слишком ограничены для Python, обычно переходят на C++ и тщательно оптимизируют реализацию (используют быструю работу с массивами, убирают лишние проверки и т.п.).

Diesen Q&A teilen