题目链接:https://codeforc.es/contest/1442/problem/B
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
input
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
output
2
0
4
分析
我们先找到每个 b 在 a 中对应的位置 pos ,很明显如果 pos 左边和右边都是无关元素的话就有两种情况,如果只有一个无关元素的话那就只有一种情况。
怎么确定两边是否是无关元素呢,我们发现在 b 中的顺序在 x 前面的,都是 x 的无关元素(因为他们已经被选过了),那么我们可以得出:
ans = ans * ((a[pos[b[i]] - 1] < a[pos[b[i]]]) + (a[pos[b[i]] + 1] < a[pos[b[i]]])) % mod;
注意 a[i] 的意义为第 i 个数在 b 中出现的次序,如果没有出现,则为 0 。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 998244353;
ll t;
ll n,k;
ll a[200007];
ll b[200007];
ll pos[200007];
int main()
{
scanf("%lld",&t);
while(t--)
{
ll ans = 1;
scanf("%lld%lld",&n,&k);
a[0] = a[n + 1] = INT_MAX;
for(int i=1;i<=n;i++)
{
ll x;
scanf("%lld",&x);
pos[x] = i;
a[i] = 0;
}
for(int i=1;i<=k;i++)
{
scanf("%lld",&b[i]);
a[pos[b[i]]] = i;
}
for(int i=1;i<=k;i++)
ans = ans * ((a[pos[b[i]] - 1] < a[pos[b[i]]]) + (a[pos[b[i]] + 1] < a[pos[b[i]]])) % mod;
printf("%lld\n",ans);
}
return 0;
}
1338

被折叠的 条评论
为什么被折叠?



