import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

public class ForkJoinMatrixProcessor {
    private static class MatrixTask extends RecursiveAction {
        private final double[][] matrix;
        private final int startRow, endRow;
        private final double average;

        MatrixTask(double[][] matrix, int startRow, int endRow, double average) {
            this.matrix = matrix;
            this.startRow = startRow;
            this.endRow = endRow;
            this.average = average;
        }

        @Override
        protected void compute() {
            if (endRow - startRow <= 10) { // Базовый случай: обрабатываем небольшой блок
                for (int i = startRow; i < endRow; i++) {
                    for (int j = 0; j < matrix[i].length; j++) {
                        matrix[i][j] /= average;
                    }
                }
            } else { // Рекурсивный случай: разбиваем задачу на две части
                int mid = (startRow + endRow) / 2;
                invokeAll(
                        new MatrixTask(matrix, startRow, mid, average),
                        new MatrixTask(matrix, mid, endRow, average)
                );
            }
        }
    }

    public static void process(double[][] matrix) {
        int rows = matrix.length;
        int cols = matrix[0].length;

        // Вычисляем среднее арифметическое
        double sum = 0;
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                sum += matrix[i][j];
            }
        }
        double average = sum / (rows * cols);

        // Создаем и запускаем задачу в ForkJoinPool
        ForkJoinPool pool = new ForkJoinPool();
        pool.invoke(new MatrixTask(matrix, 0, rows, average));
        pool.shutdown();
    }
}
