题意:
给定长度为n的数组A和长度为k的数组B
现在需要从A中取出k个数 要和B数组一样。
取数规则
1.选择ti Ati-1或Ati+1可以加入到B数组
2.把选择的ti 踢出去 Ati+1~Atn 各左移一位
3.重复1直到选出k个数
问?
问有多少种不同的取法使得取出k个数和数组B完全一致
解析:
一眼看上去就是组合数,突破口就是从B数组中的每一位进行讨论
因为bi 只可能来自 Ati-1 ,Ati+1 这2种可能
分情况
第一种情况 :假设bi在A数组的下标为x ,如果A[x-1]和A[x+1] 不是B数组要求的数,那么取得bi 就存在2种可能
第二种情况: 假设bi在A数组的下标为x ,如果A[x-1]和A[x+1] ,有一个是在B数组的,那么取得bi 就存在1种可能
第二种情况: 假设bi在A数组的下标为x ,如果A[x-1]和A[x+1] ,两个都在B数组的,那么取得bi 就存在1=0种可能
最后根据乘法原理 就是B数组每个数的取法的个数乘积。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=2e5+10000;
const int MOD=998244353;
int a[N],b[N];
int vis[N],st[N];
int t,n,k;
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),vis[a[i]]=i;
for(int i=1;i<=k;i++) scanf("%d",&b[i]),st[b[i]]=i;
ll ans=1;
for(int i=1;i<=k;i++)
{
ll cnt=0;
if(vis[b[i]]!=n&&st[a[vis[b[i]]+1]]==0) cnt++;
if(vis[b[i]]!=1&&st[a[vis[b[i]]-1]]==0) cnt++;
//cout<<cnt<<endl;
ans=ans*cnt%MOD;
st[b[i]]=0;
}
printf("%lld\n",ans%MOD);
for(int i=1;i<=n;i++) vis[i]=st[i]=0;
}
}