Codeforces Round #681 (Div. 1, based on VK Cup 2019-2020 - Final)——B. Identify the Operations
We start with a permutation a1,a2,…,an and with an empty array b. We apply the following operation k times.
On the i-th iteration, we select an index ti (1≤ti≤n−i+1), remove ati from the array, and append one of the numbers ati−1 or ati+1 (if ti−1 or ti+1 are within the array bounds) to the right end of the array b. Then we move elements ati+1,…,an to the left in order to fill in the empty space.
You are given the initial permutation a1,a2,…,an and the resulting array b1,b2,…,bk. All elements of an array b are distinct. Calculate the number of possible sequences of indices t1,t2,…,tk modulo 998244353.
Input
Each test contains multiple test cases. The first line contains an integer t (1≤t≤100000), denoting the number of test cases, followed by a description of the test cases.
The first line of each test case contains two integers n,k (1≤k<n≤200000): sizes of arrays a and b.
The second line of each test case contains n integers a1,a2,…,an (1≤ai≤n): elements of a. All elements of a are distinct.
The third line of each test case contains k integers b1,b2,…,bk (1≤bi≤n): elements of b. All elements of b are distinct.
The sum of all n among all test cases is guaranteed to not exceed 200000.
Output
For each test case print one integer: the number of possible sequences modulo 998244353.
Example
inputCopy
3
5 3
1 2 3 4 5
3 2 5
4 3
4 3 2 1
4 3 1
7 4
1 4 7 3 6 2 5
3 2 4 5
outputCopy
2
0
4
Note
Let’s denote as a1a2…aiai+1––––…an→a1a2…ai−1ai+1…an−1 an operation over an element with index i: removal of element ai from array a and appending element ai+1 to array b.
In the first example test, the following two options can be used to produce the given array b:
123–45→12–35→125–→12; (t1,t2,t3)=(4,3,2);
123–45→12–35→235–→15; (t1,t2,t3)=(4,1,2).
In the second example test, it is impossible to achieve the given array no matter the operations used. That’s because, on the first application, we removed the element next to 4, namely number 3, which means that it couldn’t be added to array b on the second step.
In the third example test, there are four options to achieve the given array b:
1473–625→14362–5→14–325→4325–→435;
1473–625→14362–5→14–325→1425–→145;
1473–625→14732–5→14–725→4725–→475;
1473–625→14732–5→14–725→1425–→145;
题意: 这个题的意思是给你一个a数组,然后你能选择一个数把他删除,同时把这个数的左边的数或者右边的数放入b数组(一开始为空)。现在给了你操作完之后的b数组,问你有多少种操作的方法可以实现,最后答案取模。
思路: 看到这道题的第一反应就是排列组合,后来细细想了一下,发现我们必须按照他给的b数组的顺序来操作,所以问题就细分为对于每一次操作来说,他可能存在几种情况。我们发现,我们要选择的数就是我们要删除的数的左边或右边的数,所以我们对于选的每个数只要考虑是删左边还是右边,如果那个数也是操作数并且还没有操作那就不能删,边界上也要考虑,之后把每个数的情况乘起来取模,答案就出来了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e6+7;
const ll mod=998244353;
int a[maxn];
int dis[maxn];
int b[maxn];
int vis[maxn];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
dis[a[i]]=i;
}
for(int i=1;i<=k;i++)
{
scanf("%d",&b[i]);
vis[b[i]]=1;
}
ll ans=1;
int flag=0;
for(int i=1;i<=k;i++)
{
flag=0;
if(dis[b[i]]!=1&&vis[a[dis[b[i]]-1]]==0)
{
flag++;
}
if(dis[b[i]]!=n&&vis[a[dis[b[i]]+1]]==0)
{
flag++;
}
vis[a[dis[b[i]]]]=0;
ans=ans*flag%mod;
}
printf("%lld\n",ans);
for(int i=1;i<=n;i++)
{
dis[i]=a[i]=b[i]=vis[i]=0;
}
}
return 0;
}