在计算机科学中,缓存算法(也常被称为缓存替换算法或缓存替换策略)是计算机程序或硬件维护的结构用于管理存储在计算机上的信息缓存的优化指令或算法。缓存通过将近期或经常使用的数据项保存在比普通内存存储访问速度更快或计算成本更低的内存位置中,从而提高性能。当缓存已满时,算法必须选择要丢弃哪些项目,以便为新项目腾出空间。
最著名的缓存算法之一是最近最少使用(Least Recently Used, LRU)算法。在 LRU 中,缓存中的项目通常由链表维护。当访问一个项目时,如果它已经在链表中,则将其从链表中移除,然后插入到链表头部。链表头部是最近使用过的项目。由于使用过的项目不断被移动到链表头部,最少使用的项目自然会移动到链表尾部。当缓存空间不足时,链表尾部的项目将被丢弃。
在本题中,为了方便起见,缓存中的每个项目都被赋予一个唯一的正整数标识符。例如,考虑访问序列 $\{4, 3, 4, 2, 3, 1, 4\}$ 并假设缓存容量为 $3$。下表显示了链表的内容。
| 步骤 | 链表内容 | 操作 |
|---|---|---|
| 1 | 访问 4 | |
| 2 | 4 | 访问 3 |
| 3 | 3 $\to$ 4 | 访问 4(已在缓存中) |
| 4 | 4 $\to$ 3 | 访问 2 |
| 5 | 2 $\to$ 4 $\to$ 3 | 访问 3(已在缓存中) |
| 6 | 3 $\to$ 2 $\to$ 4 | 访问 1(从尾部弹出 4) |
| 7 | 1 $\to$ 3 $\to$ 2 | 访问 4(从尾部弹出 2) |
| 8 | 4 $\to$ 1 $\to$ 3 |
现在,你想要对你的程序进行一些内存优化。为此,你将进行一些实验。假设 LRU 算法用于管理缓存。你程序的访问序列是已知且固定的,你想要对缓存进行 $q$ 次实验。在第 $i$ 次($1 \le i \le q$)实验中,缓存容量设置为 $m_i$,并且你有一个链表 $x_i$。你想要找出在程序执行过程中的某个时刻,LRU 算法维护的链表是否与 $x_i$ 完全相同。
在你开始运行程序进行实验之前,你的一个朋友向你发起挑战,要求你在不实际运行 $q$ 次实验的情况下找出结果。他让你写一个简单的程序来找出答案,你能做到吗?
输入格式
输入包含多个测试用例。输入的第一行包含一个正整数 $T$,表示测试用例的数量。
对于每个测试用例,第一行包含两个整数 $n, q$ ($1 \le n \le 5\,000, 1 \le q \le 2\,000$),分别表示访问序列的长度和实验次数。第二行包含 $n$ 个整数 $a_1, a_2, \dots, a_n$ ($1 \le i \le n, 1 \le a_i \le n$),其中第 $i$ 个整数表示第 $i$ 次操作中访问的项目标识符。
接下来的 $q$ 行,每行描述一个实验。第 $i$ 次($1 \le i \le q$)实验的行包含一个整数 $m_i$ ($1 \le m_i \le n$),表示缓存容量,随后是 $m_i$ 个整数 $x_{i,1}, x_{i,2}, \dots, x_{i,m_i}$ ($1 \le j \le m_i, 0 \le x_{i,j} \le n$),其中第 $j$ 个整数表示链表 $x_i$ 中第 $j$ 个项目的标识符。注意,$x_i$ 中的项目数量可能少于 $m_i$。设 $L_i$ 为 $x_i$ 的长度,则输入中最后 $m_i - L_i$ 个整数将等于 $0$,这些零应该被忽略,而其他整数将是正数。
保证所有测试用例中 $n$ 的总和不超过 $20\,000$,所有测试用例中 $q$ 的总和不超过 $20\,000$,且所有测试用例中 $m_i$ 的总和不超过 $2 \cdot 10^6$。
输出格式
对于每个测试用例,打印 $q$ 行,其中第 $i$ 行描述第 $i$ 次实验的结果。如果在某个时刻,LRU 算法维护的链表等于给定的链表 $x_i$,则打印字符串 “Yes”(不含引号)。否则,打印字符串 “No”(不含引号)。
样例
样例输入 1
1 7 5 4 3 4 2 3 1 4 1 4 2 2 3 3 3 2 1 4 4 1 3 2 4 3 4 0 0
样例输出 1
Yes No No Yes Yes