#include <stdio.h>
#include <mpi.h>

int main(void) {
    int rank, size;
    MPI_Init(NULL, NULL);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    int n = 0;
    if (rank == 0) n = 12;
    MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);

    /* Equal blocks require at least one trapezoid per rank. */
    if (n < size || n % size != 0) {
        if (rank == 0) printf("Choose n divisible by the process count.\n");
        MPI_Finalize();
        return 1;
    }

    const double a = 0.0, b = 1.0;
    const double h = (b - a) / n;
    const int local_n = n / size;
    double local_area = 0.0;

    for (int j = 0; j < local_n; j++) {
        int i = rank * local_n + j;
        double left = a + i * h;
        double right = left + h;
        local_area += h * (left * left + right * right) / 2.0;
    }

    double total_area = 0.0;
    MPI_Reduce(&local_area, &total_area, 1, MPI_DOUBLE,
               MPI_SUM, 0, MPI_COMM_WORLD);

    if (rank == 0) {
        printf("Trapezoids: %d; processes: %d\n", n, size);
        printf("Estimated area: %.9f\n", total_area);
        printf("Exact area:     %.9f\n", 1.0 / 3.0);
    }

    MPI_Finalize();
    return 0;
}
