import java.util.concurrent.*;
public class ThreadPoolAverage {
    public static double calculate(int[][] matrix, int numThreads) throws InterruptedException, ExecutionException {
        ExecutorService executor = Executors.newFixedThreadPool(numThreads);
        int size = matrix.length;
        int chunkSize = size / numThreads;
        Future<Long>[] futures = new Future[numThreads];
        int[] counts = new int[numThreads];

        for (int t = 0; t < numThreads; t++) {
            final int startRow = t * chunkSize;
            final int endRow = (t == numThreads - 1) ? size : startRow + chunkSize;
            final int threadIndex = t;
            futures[t] = executor.submit(() -> {
                long localSum = 0;
                int localCount = 0;
                for (int i = startRow; i < endRow; i++) {
                    for (int j = 0; j < i; j++) {
                        localSum += matrix[i][j];
                        localCount++;
                    }
                }
                counts[threadIndex] = localCount;
                return localSum;
            });
        }

        long totalSum = 0;
        int totalCount = 0;
        for (int t = 0; t < numThreads; t++) {
            totalSum += futures[t].get();
            totalCount += counts[t];
        }

        executor.shutdown();
        return (double) totalSum / totalCount;
    }
}
