The Forbidden Permutation

一,题目

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≤mn, 1≤dn), 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:

  1. Swap p3 and p4.

  1. Swap p2 and p3.

  1. 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:

  1. Swap p4 and p5.

  1. 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:

  1. Swap p1 and p2.

  1. Swap p5 and p6.

二,思路

(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;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值