i
−
−
>
p
i
−
−
>
q
p
i
i-->p_i-->q_{pi}
i−−>pi−−>qpi
要满足条件
i
=
q
p
i
i=q_{pi}
i=qpi,那么只需
q
j
=
i
q_j=i
qj=i中的
j
=
p
i
j=p_i
j=pi
为此我们求出每个数字在数组中的pos,存在b中
之后验证只需查看
a
i
a_i
ai ,
b
j
b_j
bj中最长共前缀
对于一个
a
i
a_i
ai 暴力查找 最长公共前缀的
b
j
b_j
bj 需要O(n*m),再循环操作总共需要
O
(
m
n
2
)
O(m n^2)
O(mn2)
先对
b
b
b 整体排序,之后二分查找与
a
i
a_i
ai 最相近的
b
j
b_j
bj 即可 排序预处理 总时间复杂度为
O
(
m
n
l
o
g
n
)
O(mnlogn)
O(mnlogn)
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int lcp(vector<int> a,vector<int> b){
int i=1;
for (i=1;a[i]==b[i]&&i<a.size();i++){
;
}
return i-1;
}
void solve(){
int n,m;
cin>>n>>m;
vector<vector<int>> a(n+1,vector<int>(m+1)),b(n+1,vector<int>(m+1));
for (int i=1;i<=n;i++){
for (int j=1;j<=m;j++){
cin>>a[i][j];
b[i][a[i][j]]=j;
}
}
sort(b.begin()+1,b.end());
for (int i=1;i<=n;i++){
int p=lower_bound(b.begin()+1,b.end(),a[i])-b.begin(),ans=0;
if (p>=2) ans=max(ans,lcp(a[i],b[p-1]));
if (p<=n) ans=max(ans,lcp(a[i],b[p]));
cout<<ans<<" ";
}
cout<<"\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while (t--){
solve();
}
return 0;
}