Mam bardzo ciekawe zadanie ,z którym mam problem jak je zacząć

Zadanie
Oblicz:
X = (N mod 4).
Napisz szablonową funkcję rng(n, m, f), która otrzyma parametry n i m typu generycznego T
oraz funkcję lambda f. Funkcja rng powinna obliczyć i zwrócić wartość wyrażenia po n
iteracjach:
Ri = f(Ri-1
, Ri - 2
) mod m.
Wartości początkowe przyjmij:
R0 = (T)std::time(0),
R1 = X
2 + 1.
Takie wyrażenie zwróci wartość pseudolosową z przedziału od 0 do m - 1. Funkcja std::time
zdefiniowana jest w pliku nagłówkowym ctime.
Niech dana będzie klasa abstrakcyjna:
class Set {
public:
explicit Set(size_t size) : size(size) {}
virtual ~Set() {}
size_t get_size() const {return size;}
virtual const int & operator[](size_t n) = 0;
private:
size_t size;
};
Napisz klasę pochodną klasy Set, w której:

  • zdefiniujesz prywatne pole typu wskaźnik na typ int;
  • przypiszesz w konstruktorze do pola klasy adres dynamicznie zarezerwowanej
    tablicy o rozmiarze size. Wypełnij tablicę wartościami zgodnie z:
    1a19
  • dla X = 0, do i-tego elementu tablicy przypisz wartość zwróconą przez funkcję
    rng, gdzie n = (i + N) mod 100, m = 101, a f to funkcja lambda zwracająca
    różnicę symetryczną (xor) przekazanych elementów.
  • dla X = 1, do i-tego elementu tablicy przypisz wartość zwróconą przez funkcję
    rng, gdzie n = (i + N) mod 100, m = 101, a f to funkcja lambda zwracająca
    sumę przekazanych elementów.
  • dla X = 2, do i-tego elementu tablicy przypisz wartość zwróconą przez funkcję
    rng, gdzie n = (i + N) mod 100, m = 101, a f to funkcja lambda zwracająca
    iloczyn przekazanych elementów.
  • dla X = 3, do i-tego elementu tablicy przypisz wartość zwróconą przez funkcję
    rng, gdzie n = (i + N) mod 100, m = 101, a f to funkcja lambda zwracająca
    różnicę przekazanych elementów.
  • zdefiniujesz konstruktor kopiujący;
  • zdefiniujesz destruktor;
  • zdefiniujesz operator przypisania (=);
  • przeciążysz operator[] z klasy bazowej - operator powinien zwracać n-ty element z
    tablicy, jeśli przekazano wartość n wykraczającą poza zakres tablicy zachowanie
    metody powinno być nieokreślone.
    Napisz funkcję exists, która otrzyma wskaźnik na typ Set, rozmiar zbioru, oraz funkcję
    lambda. Funkcja exists powinna wywołać dla każdego elementu zbioru funkcję lambda, jeśli
    dla choć jednego elementu zbioru funkcja lambda zwróci true, wynik funkcji exists powinien
    być true, w przeciwnym razie false. Napisz funkcję main, gdzie stworzysz obiekt typu klasy
    pochodnej i przetestujesz funkcję exists dla:
  • X = 0, funkcja lambda zwraca logiczną prawdę dla wartości większych od 50;
  • X = 1, funkcja lambda zwraca logiczną prawdę dla wartości parzystych;
  • X = 2, funkcja lambda zwraca logiczną prawdę dla wartości nieparzystych;
  • X = 3, funkcja lambda zwraca logiczną prawdę dla wartości mniejszych od 50.