Codeforces Round #681 (Div. 1, based on VK Cup 2019-2020 - Final)——B. Identify the Operations(思维+组合)

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;
 } 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值