D. Fixed Prefix Permutations

D. Fixed Prefix Permutations

You are given $n$ permutations $a_1, a_2, \dots, a_n$, each of length $m$. Recall that a permutation of length $m$ is a sequence of $m$ distinct integers from $1$ to $m$.

Let the beauty of a permutation $p_1, p_2, \dots, p_m$ be the largest $k$ such that $p_1 = 1, p_2 = 2, \dots, p_k = k$. If $p_1 \neq 1$, then the beauty is $0$.

The product of two permutations $p \cdot q$ is a permutation $r$ such that $r_j = q_{p_j}$.

For each $i$ from $1$ to $n$, print the largest beauty of a permutation $a_i \cdot a_j$ over all $j$ from $1$ to $n$ (possibly, $i = j$).

Input

The first line contains a single integer $t$ ($1 \le t \le 10^4$) — the number of testcases.

The first line of each testcase contains two integers $n$ and $m$ ($1 \le n \le 5 \cdot 10^4$; $1 \le m \le 10$) — the number of permutations and the length of each permutation.

The $i$-th of the next $n$ lines contains a permutation $a_i$ — $m$ distinct integers from $1$ to $m$.

The sum of $n$ doesn't exceed $5 \cdot 10^4$ over all testcases.

Output

For each testcase, print $n$ integers. The $i$-th value should be equal to the largest beauty of a permutation $a_i \cdot a_j$ over all $j$ ($1 \le j \le n$).

Example

input

3
3 4
2 4 1 3
1 2 4 3
2 1 3 4
2 2
1 2
2 1
8 10
3 4 9 6 10 2 7 8 1 5
3 9 1 8 5 7 4 10 2 6
3 10 1 7 5 9 6 4 2 8
1 2 3 4 8 6 10 7 9 5
1 2 3 4 10 6 8 5 7 9
9 6 1 2 10 4 7 8 3 5
7 9 3 2 5 6 4 8 1 10
9 4 3 7 5 6 1 10 8 2

output

1 4 4 
2 2 
10 8 1 6 8 10 1 7 

 

解题思路

  暴力做法是直接枚举全部排列,本质上给定一个排列$p$,从所有的排列中找到一个$q_i$使得$p \cdot q_i$的美丽值最大,假设最大值为$k$,那么$p \cdot q_i$得到的排列就是$\{ 1,2, \ldots k, q_{p_{k+1}} \ ,  \ldots, q_{p_{m}} \}$。注意到就是求从$1$开始的上升前缀最长是多少。因此可以考虑用trie来存$n$个排列的信息,然后再枚举每一个排列来得到答案。

  对于一个排列$p$,如果答案至少是$1$,那么首先就要找到第$p[1]$个位置是数值$1$的所有排列,以此类推如果答案至少是$2$,那么就要从第$p[1]$个位置是数值$1$的所有排列中再找到第$p[2]$个位置为$2$的排列。因此我们可以在trie中存每个排列中每个数值在排列中的下标位置,查询的时候就依次遍历$p[i]$,这样就可以找到一个匹配的最大前缀。

  AC代码如下,时间复杂度为$O(n \times m)$:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 int n, m;
 5 vector<vector<int>> a, tr;
 6 int idx;
 7 int pos[20];
 8 
 9 void insert() {
10     int p = 0;
11     for (int i = 1; i <= m; i++) {
12         if (!tr[p][pos[i]]) tr[p][pos[i]] = ++idx;
13         p = tr[p][pos[i]];
14     }
15 }
16 
17 int query(int u) {
18     int p = 0, ret = 0;
19     for (int i = 1; i <= m; i++) {
20         if (!tr[p][a[u][i]]) break;
21         ret++;
22         p = tr[p][a[u][i]];
23     }
24     return ret;
25 }
26 
27 void solve() {
28     scanf("%d %d", &n, &m);
29     idx = 0;
30     tr = vector<vector<int>>(n * m + 1, vector<int>(m + 1));
31     a = vector<vector<int>>(n + 1, vector<int>(m + 1));
32     for (int i = 1; i <= n; i++) {
33         for (int j = 1; j <= m; j++) {
34             scanf("%d", &a[i][j]);
35             pos[a[i][j]] = j;
36         }
37         insert();
38     }
39     for (int i = 1; i <= n; i++) {
40         printf("%d ", query(i));
41     }
42     printf("\n");
43 }
44 
45 int main() {
46     int t;
47     scanf("%d", &t);
48     while (t--) {
49         solve();
50     }
51 }

 

参考资料

  Educational Codeforces Round 142 D(思维+字典树):https://zhuanlan.zhihu.com/p/600835977

原文链接: https://www.cnblogs.com/onlyblues/p/17068988.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    D. Fixed Prefix Permutations

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/314323

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月16日 下午1:17
下一篇 2023年2月16日 下午1:18

相关推荐