#include <iostream>
#include <string>
using namespace std;
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
Pomysl *start; // poczatek stosu
unsigned wzor[10]; // zbiór startowy
// Metody:
Stos();
void insert_in_stack(string nazwa, unsigned CNT[]);
void reverse_stack();
void find_pomysl();
};
Pomysl::Pomysl(string nazwa, unsigned CNT[]) {
this->nazwa = nazwa;
for (int i = 0; i < 10; i++) {
this->CNT[i] = CNT[i];
}
next = NULL;
prev = NULL;
}
Stos::Stos() {
first = NULL;
last = NULL;
start = NULL;
}
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;
start = last;
}
else if (start == last) {
nowy->prev = last;
last->next = nowy;
last = nowy;
start = last;
}
else if (start == first) {
nowy->next = first;
first->prev = nowy;
first = nowy;
start = first;
}
}
void Stos::reverse_stack() {
if (start == last) {
start = first;
}
else if (start == first) {
start = last;
}
}
void Stos::find_pomysl() {
unsigned more = 0;
Pomysl *tmp1 = last;
Pomysl *tmp2 = first;
if (start == last) {
while (/*more >= 3 ||*/ tmp1 != NULL) {
for (unsigned i = 0; i<10; ++i) more += (wzor[i]<tmp1->CNT[i]);
if (more >= 3) { // pasuje
cout << tmp1->nazwa << endl; // wyświetla nazwę
for (int i = 0; i < 10; i++) {
wzor[i] = tmp1->CNT[i];
}
// i usuwa:
if (tmp1 == last) {
last->prev->next = NULL;
last = last->prev;
start = last;
break;
}
else if (tmp1 == first) {
first->next->prev = NULL;
first = first->next;
break;
}
else { // w środku
tmp1->prev->next = tmp1->next;
tmp1->next->prev = tmp1->prev;
break;
}
}
else { // znajduje niepasujący
// usuwa:
if (tmp1 == last) {
last->prev->next = NULL;
last = last->prev;
start = last;
}
else if (tmp1 == first) {
first->next->prev = NULL;
first = first->next;
}
else { // w środku
tmp1->prev->next = tmp1->next;
tmp1->next->prev = tmp1->prev;
}
}
tmp1 = tmp1->prev;
}
}
else if (start == first) {
while (/*more >= 3 || */tmp2 != NULL) {
for (unsigned i = 0; i<10; ++i) more += (wzor[i]<tmp2->CNT[i]);
if (more >= 3) { // pasuje
cout << tmp2->nazwa << endl; // wyświetla nazwę
for (int i = 0; i < 10; i++) {
wzor[i] = tmp2->CNT[i];
}
// i usuwa:
if (tmp2 == first) {
first->next->prev = NULL;
first = first->next;
start = first;
break;
}
else if (tmp2 == last) {
last->prev->next = NULL;
last = last->prev;
break;
}
else { // w środku
tmp2->prev->next = tmp2->next;
tmp2->next->prev = tmp2->prev;
break;
}
}
else { // znajduje niepasujący
// usuwa:
if (tmp2 == last) {
last->prev->next = NULL;
last = last->prev;
}
else if (tmp2 == first) {
first->next->prev = NULL;
first = first->next;
start = first;
}
else { // w środku
tmp2->prev->next = tmp2->next;
tmp2->next->prev = tmp2->prev;
}
}
tmp2 = tmp2->next;
}
}
else {
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];
}
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;
}*/
return 0;
}