一,题目
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given a permutation p of length n, an array of m distinct integers a1,a2,…,am (1≤ai≤n), and an integer d.
Let pos(x) be the index of x in the permutation p. The array a is not good if
pos(ai)<pos(ai+1)≤pos(ai)+d for all 1≤i<m.
For example, with the permutation p=[4,2,1,3,6,5] and d=2:
a=[2,3,6] is a not good array.
a=[2,6,5] is good because pos(a1)=2, pos(a2)=5, so the condition pos(a2)≤pos(a1)+d is not satisfied.
a=[1,6,3] is good because pos(a2)=5, pos(a3)=4, so the condition pos(a2)<pos(a3) is not satisfied.
In one move, you can swap two adjacent elements of the permutation p. What is the minimum number of moves needed such that the array a becomes good? It can be shown that there always exists a sequence of moves so that the array a becomes good.
A permutation is an array consisting of n distinct integers from 1 to n in arbitrary order. For example, [2,3,1,5,4] is a permutation, but [1,2,2] is not a permutation (2 appears twice in the array) and [1,3,4] is also not a permutation (n=3, but there is 4 in the array).
Input
Each test contains multiple test cases. The first line contains the number of test cases t (1≤t≤104). The description of the test cases follows.
The first line of each test case contains three integers n, m and d (2≤n≤10^5, 2≤m≤n, 1≤d≤n), the length of the permutation p, the length of the array a and the value of d.
The second line contains n integers p1,p2,…,pn (1≤pi≤n, pi≠pj for i≠j).
The third line contains m distinct integers a1,a2,…,am (1≤ai≤n, ai≠aj for i≠j).
The sum of n over all test cases doesn't exceed 5*10^5.
Output
For each test case, print the minimum number of moves needed such that the array a becomes good.
Example
Input
5
4 2 2
1 2 3 4
1 3
5 2 4
5 4 3 2 1
5 2
5 3 3
3 4 1 5 2
3 1 2
2 2 1
1 2
2 1
6 2 4
1 2 3 4 5 6
2 5
Output
1
3
2
0
2
Note
In the first case, pos(a1)=1, pos(a2)=3. To make the array good, one way is to swap p3 and p4. After that, the array a will be good because the condition pos(a2)≤pos(a1)+d won't be satisfied.
In the second case, pos(a1)=1, pos(a2)=4. The 3 moves could be:
Swap p3 and p4.
Swap p2 and p3.
Swap p1 and p2.
After these moves, the permutation p will be [2,5,4,3,1]. The array a will be good because the condition pos(a1)<pos(a2) won't be satisfied. It can be shown that you can't make the array a good with fewer moves.
In the third case, pos(a1)=1, pos(a2)=3, pos(a3)=5. The 2 moves can be:
Swap p4 and p5.
Swap p3 and p4.
After these moves, the permutation p will be [3,4,2,1,5]. The array a will be good because the condition pos(a2)<pos(a3) won't be satisfied. It can be shown that you can't make the array a good with fewer moves.
In the fourth case, pos(a1)=2, pos(a2)=1. The array a is already good.
In the fifth case, pos(a1)=2, pos(a2)=5. The 2 moves are:
Swap p1 and p2.
Swap p5 and p6.
![](https://i-blog.csdnimg.cn/blog_migrate/a4cea5d15a4c4da0d2274afc88c03cf2.png)
二,思路
(1)因为只要保证a数组中有一对和
不满足pos(
)<pos(
)≤pos(
)+d就能够满足答案要求,所以最优方案肯定只改变一对
和
在p数组中的相对位置(pos(
)即ai在p数组中的位置),或者无须改变任何操作(可能a数组已经有一对
和
不满足pos(
)<pos(
)≤pos(
)+d,所以接下来的思路就是如何改变
和
在p数组中的相对位置使得交换数组p中数字的次数最小。
(2)首先,思路一,让pos()>pos(
),仔细一想,就是让
在p中的相对位置在
右边,说白了就是
一直与其他数交换,直到换的
的左边。这时,想要交换次数最小,我们就需要定义一个变量MIN,用来找到所有
和
的中在p数组中的最小相对距离。根据这个思路,我们可以得到最小的交换次数为MIN。
(3)其次,思路二,让pos()>pos(
)+d,当然,这个是不可能的,pos(
)
pos(
)+d,即pos(
)-pos(
)
d,说白了,就是
的相对位置在
左边,且距离至少为d。这时,想要交换次数最小,我们就需要定义一个变量MAX,用来找到所有
和
的中在p数组中的最大相对距离。根据这个思路,我们可以得到的最小交换次数为d-MAX+1(不知道为啥要加1,反正当时看到自己运行结果和答案少了个一就加了一)。
(4)然后,就是一些特判,首先,如果MIN为负数的话,就说明肯定存在一对和
,使得pos(
)-pos(
)>0,既然这样,那就不用交换了,即交换次数为0。其次,如果MAX>d,就说明pos(
)-pos(
)>=d,也是不用交换。最后,就是如果d>n-1的话,pos(
)-pos(
)将不可能大于等于d,所以这种情况下只能用思路一。
(5)那么什么情况下用思路一或二呢,什么情况都用,到最后得到MIN和MAX,我们就判断一下思路一的最小交换次数和思路二哪个交换次数小,然后输出小的。当然,d>n-1的话只能输出MIN。
三,代码
#include<iostream>
#include<cmath>
using namespace std;
#define int long long
#define endl '\n'
int p[200005]={0},a[200005]={0},book[200005]={0};
signed main()
{
ios::sync_with_stdio(false); cin.tie(0),cout.tie(0);
int t;
cin>>t;
while(t--)
{
int n,m,d;
cin>>n>>m>>d;
int MIN=n+1,MAX=-n-1;
for(int i=0;i<n;++i) cin>>p[i],book[p[i]]=i+1;//book用于记录a[i]在数组p中的相对距离
for(int i=0;i<m;++i)
{
cin>>a[i];
if(i!=0)
{
MIN=min(book[a[i]]-book[a[i-1]],MIN);
MAX=max(book[a[i]]-book[a[i-1]],MAX);
}
}
if(MAX>d||MIN<0) cout<<0<<endl;
else
{
if(d-MAX+1<=MIN&&d<n-1) cout<<d-MAX+1<<endl;
else cout<<MIN<<endl;
}
}
return 0;
}