El objetivo del programa es generar un conjunto aleatorio de ganadores a partir de un número de participantes y un número de ganadores especificado por el usuario. El programa verifica que el número de ganadores sea menor o igual al número de participantes y luego utiliza un generador de números aleatorios para seleccionar al azar los ganadores y los almacena en un vector.  Por cada ejecución, el programa obtendrá una selección de ganadores diferente y se muestrará el resultado en una lista numerada del 0 a 'n' números. Este programa es ideal para sorteos y rifas pequeños.

#include <iostream>
#include <random>
#include <vector>
#include <chrono>
#include <set>

int main() {
    int n, m;

    std::cout << "Ingrese el número de participantes: ";
    std::cin >> n;
    std::cout << "Ingrese el número de ganadores: ";
    std::cin >> m;

    if (m > n) {
        std::cerr << "Error: el número de ganadores no puede ser mayor al número de participantes." << std::endl;
        return 1;
    }

    // Creamos un vector con los números de los participantes
    std::vector<int> numbers(n);

    // Generamos una semilla para la generación de números aleatorios a partir de la hora actual
    unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();

    // Creamos un generador de números aleatorios con la semilla generada
    std::default_random_engine generator(seed);

    // Creamos una distribución uniforme de enteros entre 1 y n para generar los números aleatorios
    std::uniform_int_distribution<int> distribution(1, n);

    // Creamos un conjunto para almacenar los números que ya fueron seleccionados como ganadores
    std::set<int> used_numbers;

    // Generamos m números aleatorios y los almacenamos en el vector de números
    for (int i = 0; i < m; i++) {
        int number;
        do {
            // Generamos un número aleatorio y verificamos que no haya sido seleccionado antes
            number = distribution(generator);
        } while (used_numbers.count(number));
        used_numbers.insert(number);
        numbers[i] = number;
    }

    // Imprimimos la lista de ganadores del 1 a n
    std::cout << "Ganadores:" << std::endl;
    for (int i = 1; i <= n; i++) {
        std::cout << i << " | ";
        int count = 0;
        for (int j = 0; j < m; j++) {
            if (numbers[j] == i) {
                count++;
            }
        }
        for (int k = 0; k < count; k++) {
            std::cout << "*";
        }
        std::cout << std::endl;
    }
  
    return 0;
}

Expliquemos más a detalle su funcionamiento: Primero se pide al usuario que ingrese un número de participantes ('n') y un número de ganadores ('m'), y se verifica que el primer valor sea menor al segundo utilizando un bucle 'if'. 

Se crea un vector entero llamado 'numbers' que podrá almacenar '(n)' números enteros y que será usado para guardar los números de los ganadores.

En la línea 'unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();' se genera una semilla para la generación de números aleatorios a partir de la hora actual, con el fin de evitar que se genere el mismo conjunto de números por cada ejecución del programa. En otras palabras, si los parámetros de entrada fueran los mismos, obtendríamos el mismo resultado en cada ejecución del programa sino se utilizara la semilla. A continuación, se explicará con más detalle qué es lo que hace esta línea de código: 

1.- Se utiliza la función std::chrono::system_clock::now() para obtener el tiempo actual en el sistema. Esta función devuelve un objeto std::chrono::system_clock::time_point, que representa el tiempo actual con una resolución determinada por el sistema.

2.- Luego, se llama al método time_since_epoch() para obtener la cantidad de tiempo transcurrida desde el punto de referencia de la época del reloj del sistema (que generalmente es 1 de enero de 1970, 00:00:00 UTC) hasta el tiempo actual, expresado en la unidad de tiempo más pequeña disponible en el sistema.

3.- Finalmente, se llama al método count() para obtener el número de unidades de tiempo transcurridas desde la época del reloj del sistema hasta el tiempo actual. Este valor es un número entero que puede ser utilizado como semilla para generar números aleatorios.

Posteriormente se define un generador de números aleatorios 'std::default_random_engine generator(seed)' que utilizará la semilla generada en el paso anterior. También se define una distribución entre 1 y 'n' para distribuir aleatoriamente los números ganadores en la lista de participantes std::uniform_int_distribution<int> distribution(1, n). Y finalmente, un conjunto para guardar temporalmente los números seleccionados como ganadores std::set<int> used_numbers;

Veamos ahora el ciclo principal 'for': Mediante (int i = 0; i < m; i++) se verifica que la variable 'i' sea menor que el número de ganadores 'm'. Luego, mediante un bucle 'do-while' se genera un número aleatorio y se guarda en la variable 'number' y se verifica mediante (used_numbers.count(number)) que no haya sido seleccionado en el conjunto 'used_numbers'. Si 'count' devuelve un 1 (algún número del conjunto se repite) vuelve a repetirse el ciclo 'do-while', si devuelve 0 (los números del conjunto no se repiten) entonces continua el proceso de ejecución. El número generado se guarda en el conjunto 'used_numbers'. Finalmente se guarda el numero en el vector 'numbers' y se vuelve a repetir el bucle 'for' hasta que la condición ya no se cumpla.

Los ganadores almacenados en el vector 'numbers' se imprimen en la pantalla mediante un ciclo 'for' y se muestran con un asterisco para indicar cuántas veces aparecieron en la lista de ganadores.

El código ha sido probado en Code::Blocks en Windows, por lo que es completamente funcional.

NOTA: Si al correr el programa los acentos o caracteres especiales no se muestran correctamente, puedes usar esta solución: ¿Cómo mostrar acentos y caracteres especiales en programas escritos en C++?