#include <iostream> // برای cin, cout, endl
#include <vector> // برای std::vector
#include <string> // برای std::string و stoi
// نیازی به <utility> یا <sstream> یا <limits> نیست.
// نیازی به using namespace std; نیست اگر به این شکل استفاده کنیم
// ولی چون قبلا درخواست کردید، اینجا هم استفاده می کنم:
using namespace std;
const int MAX_CACHE_SIZE = 20;
int main() {
// افزایش سرعت ورودی/خروجی
ios_base::sync_with_stdio(false);
cin.tie(NULL);
// حافظه کش (کوچک): از دو وکتور موازی استفاده می کنیم
vector<int> cache_indices; // نگهداری جایگاه ها
vector<int> cache_main_nums; // نگهداری اعداد اصلی متناظر
// حافظه مرکزی (بزرگ): از دو وکتور موازی استفاده می کنیم
vector<int> main_memory_indices; // نگهداری جایگاه ها
vector<int> main_memory_main_nums; // نگهداری اعداد اصلی متناظر
string command_str; // برای خواندن "end" و "give"
int val1, val2; // برای خواندن دو عدد در هر خط
// --- فاز 1: خواندن دادههای حافظه مرکزی (حافظه بزرگ) ---
// هر کلمه را به عنوان string می خوانیم تا به "end" برسیم.
while (cin >> command_str) {
if (command_str == "end") {
break; // پایان فاز خواندن دادههای مرکزی
}
// اگر "end" نبود، فرض می کنیم command_str عدد اول (main_num) است.
// آن را به int تبدیل می کنیم.
val1 = stoi(command_str); // main_number
// عدد دوم (index_val) را می خوانیم.
cin >> val2; // index_val
// ذخیره به صورت {جایگاه, عدد اصلی} برای جستجوی آسانتر با ایندکس
main_memory_indices.push_back(val2);
main_memory_main_nums.push_back(val1);
}
// --- فاز 2: پردازش درخواستهای "give" ---
// هر کلمه را می خوانیم تا به "end" دوم برسیم.
while (cin >> command_str) {
if (command_str == "end") {
break; // پایان برنامه
}
if (command_str == "give") {
cin >> val1; // val1 اینجا همان جایگاه مورد درخواست است (index_val)
bool found_in_cache = false;
int found_number = -1;
// **1. جستجو در حافظه کش (حافظه کوچک)**
for (size_t i = 0; i < cache_indices.size(); ++i) {
if (cache_indices[i] == val1) { // مقایسه با جایگاه ذخیره شده
found_in_cache = true;
found_number = cache_main_nums[i]; // عدد اصلی متناظر
break;
}
}
if (found_in_cache) {
// **Hit**
cout << "hit with " << found_number << endl;
} else {
// **Miss**: جایگاه در کش نبود
// 2. جستجو در حافظه مرکزی (حافظه بزرگ) برای پیدا کردن عدد اصلی
int main_num_from_memory = -1;
bool found_in_main_memory = false;
for (size_t i = 0; i < main_memory_indices.size(); ++i) {
if (main_memory_indices[i] == val1) { // مقایسه با جایگاه ذخیره شده
main_num_from_memory = main_memory_main_nums[i]; // عدد اصلی متناظر
found_in_main_memory = true;
break;
}
}
if (found_in_main_memory) {
cout << "miss with " << main_num_from_memory << endl;
// 3. اضافه کردن به کش: FIFO
if (cache_indices.size() == MAX_CACHE_SIZE) {
cache_indices.erase(cache_indices.begin());
cache_main_nums.erase(cache_main_nums.begin());
}
// اضافه کردن عنصر جدید به انتهای کش (به عنوان تازهترین)
cache_indices.push_back(val1);
cache_main_nums.push_back(main_num_from_memory);
}
// اگر در حافظه مرکزی هم پیدا نشد، هیچ خروجی لازم نیست.
}
}
// اگر دستور نه "give" بود و نه "end"، آن خط نادیده گرفته میشود.
}
// اطمینان از خروج تمام خروجیها قبل از پایان برنامه
cout << flush;
return 0;
}