#include <iostream>
#include <string>
using namespace std;
inline void przepisz(unsigned tab1[], unsigned tab2[]) {
static int i;
for (i = 0; i < 10; ++i) {
tab1[i] = tab2[i];
}
}
struct Pomysl {
string nazwa;
unsigned CNT[10];
Pomysl *next;
Pomysl *prev;
Pomysl(string nazwa, unsigned CNT[]);
};
struct Stos {
Pomysl *first; // pierwszy element
Pomysl *last; // ostatni element
bool start; // kolejność stosu: true - odwrócony
unsigned wzor[10]; // zbiór startowy
// Metody:
Stos();
inline unsigned zlicz(unsigned wzor[], unsigned CNT[], unsigned more);
void insert_in_stack(string nazwa, unsigned CNT[]);
void reverse_stack();
void delete_pomysl(Pomysl *x);
void find_pomysl();
};
Pomysl::Pomysl(string nazwa, unsigned CNT[]) {
this->nazwa = nazwa;
/*for (int i = 0; i < 10; i++) {
this->CNT[i] = CNT[i];
}*/
przepisz(this->CNT, CNT);
next = NULL;
prev = NULL;
}
Stos::Stos() {
first = NULL;
last = NULL;
start = false;
}
inline unsigned Stos::zlicz(unsigned wzor[], unsigned CNT[], unsigned more) {
for (unsigned i = 0; i < 10; ++i) {
if (wzor[i] != 0 && wzor[i]<CNT[i]) more++;
}
return more;
}
void Stos::insert_in_stack(string nazwa, unsigned CNT[]) {
Pomysl *nowy = new Pomysl(nazwa, CNT);
if (first == NULL) { // Pierwszy element listy
first = nowy;
last = nowy;
}
else if (start == false) {
last->next = nowy;
nowy->prev = last;
last = nowy;
}
else if (start == true) {
nowy->next = first;
first->prev = nowy;
first = nowy;
}
}
void Stos::reverse_stack() {
if (start == false) {
start = true;
}
else if (start == true) {
start = false;
}
}
void Stos::delete_pomysl(Pomysl *x) {
if (x->prev != NULL) {
x->prev->next = x->next;
}
else {
first = x->next;
}
if (x->next != NULL) {
x->next->prev = x->prev;
}
else {
last = x->prev;
}
}
void Stos::find_pomysl() {
unsigned more = 0;
bool istnieje = false;
if (first == NULL) {
istnieje = false;
}
else if (start == false) {
Pomysl *pomysl = last;
while (pomysl != NULL) {
/*for (unsigned i = 0; i < 10; ++i) {
if (wzor[i] != 0 && wzor[i]<pomysl->CNT[i]) more ++;
}*/
more = zlicz(wzor, pomysl->CNT, more);
if (more >= 3) { // pasuje
cout << pomysl->nazwa << endl; // wyświetla nazwę
/*for (int i = 0; i < 10; i++) {
wzor[i] = pomysl->CNT[i];
}*/
przepisz(wzor, pomysl->CNT);
istnieje = true;
// i usuwa:
delete_pomysl(pomysl);
more = 0;
break;
}
else { // znajduje niepasujący
// usuwa:
delete_pomysl(pomysl);
more = 0;
}
pomysl = pomysl->prev;
}
}
else if (start == true) {
Pomysl *pomysl = first;
while (pomysl != NULL) {
/*for (unsigned i = 0; i < 10; ++i) {
if (wzor[i] != 0 && wzor[i]<pomysl->CNT[i]) more ++;
}*/
more = zlicz(wzor, pomysl->CNT, more);
if (more >= 3) { // pasuje
cout << pomysl->nazwa << endl; // wyświetla nazwę
/*for (int i = 0; i < 10; i++) {
wzor[i] = pomysl->CNT[i];
}*/
przepisz(wzor, pomysl->CNT);
istnieje = true;
// i usuwa:
delete_pomysl(pomysl);
more = 0;
break;
}
else { // znajduje niepasujący
// usuwa:
delete_pomysl(pomysl);
more = 0;
}
pomysl = pomysl->next;
}
}
if (istnieje == false) {
cout << "NIE" << endl;
}
}
int main() {
int n; // liczba operacji
int s; // liczba cyfr w opisie startowym
string nazwa; // nazwa pomysłu
unsigned m; // liczba cyfr w opisie pomysłu
int op; // rodzaj operacji
Stos *stos = new Stos;
cin >> n;
unsigned stan[10] = {}; // stan startowy
unsigned v = 0; // pomocniczo el. tablicy
for (cin >> s; s--; ++stan[v]) cin >> v;
/*for (int i = 0; i < 10; i++) {
stos->wzor[i] = stan[i];
//cout << stos->wzor[i] << endl;;
}*/
przepisz(stos->wzor, stan);
for (int i = 0; i < n; i++) {
cin >> op;
if (op == 1) {
// operacja dodawania pomysłu
cin.ignore();
getline(cin, nazwa);
unsigned CNT[10] = {};
unsigned V = 0; // pomocniczo el. tablicy
for (cin >> m; m--; ++CNT[V]) cin >> V;
// funkcja dodająca
stos->insert_in_stack(nazwa, CNT);
}
else if (op == 2) {
// zmiana kolejności
stos->reverse_stack();
}
else if (op == 3) {
// poszukiwanie pomysłu
stos->find_pomysl();
}
}
/*
for (int i = 0; i < 10; i++) {
cout << stos->first->CNT[i] << endl;
}
cout << "wzor:" << endl;
for (int i = 0; i < 10; i++) {
cout << stos->wzor[i] << endl;
}*/
/*
cout << stos->last->nazwa << endl;
cout << stos->last->prev->nazwa << endl;
cout << stos->last->prev->prev->nazwa << endl;
/*
cout << stos->first->nazwa << endl;
cout << stos->first->next->nazwa << endl;
cout << stos->first->next->next->nazwa << endl;*/
return 0;
}