Description
给定两个数组 (a,b),长度分别为 (n,m( m le n))。(a) 是 (1..n) 的全排列,(b) 是一个 (1..n) 的 (m) 排列。(b) 是目标序列,即我们需要通过以下的操作来构造一个答案序列使其等于 (b)。每次操作选择一个 (t),将 (a_{t-1}) 或 (a_{t+1}) 插入答案序列末尾并将 (a_t) 删除。问有多少种不同的构造方案。
Solution
考虑对于出现在 (b) 中的每一个 (a_i),我们必然要删除 (a_{i-1}) 和 (a_{i+1}) 中的至少一个。
设 (f(a_i)) 表示 (a_i) 在 (b) 中的出现位置。
如果 (a_{i-1}) 存在,并且 (f(a_{i-1}) le f(a_{i})),那么我们称这个 (a_{i-1}) 对于 (a_i) 是合法的。(a_{i+1}) 同理。
对于 (a_i),有如下三种情况:
-
如果 (a_{i-1},a_{i+1}) 均合法,那么我们可以删除任意一个,方案数乘 (2)。之所以现在可以删除任意,是因为 (a_{i-1},a_i,a_{i+1}) 的出现位置必然都在 (b) 中后面所有数之前,因此他们并没有区别。
-
如果 (a_{i-1},a_{i+1}) 中恰好有一个合法,那么我们把它删除即可。
-
如果 (a_{i-1},a_{i+1}) 均不合法,则无解。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 998244353;
const int N = 1000005;
struct Node
{
int val;
Node *prec = NULL;
Node *succ = NULL;
} node[N];
void deleteNode(Node *p)
{
if (p == NULL)
return;
Node *prec = p->prec;
Node *succ = p->succ;
p->prec = p->succ = NULL;
if (prec)
prec->succ = succ;
if (succ)
succ->prec = prec;
}
void deleteNode(Node &p)
{
deleteNode(&p);
}
int n, m, a[N], b[N], f[N], c[N];
void clearall(int n)
{
for (int i = 0; i <= n+1; i++)
a[i] = b[i] = f[i] = c[i] = node[i].val = 0,
node[i].prec = node[i].succ = 0;
}
void solve()
{
cin >> n >> m;
clearall(n);
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= m; i++)
cin >> b[i];
for (int i = 1; i <= m; i++)
f[b[i]] = i;
for (int i = 1; i <= n; i++)
node[i].val = a[i];
for (int i = 1; i <= n; i++)
node[i].prec = node[i].succ = NULL;
for (int i = 1; i < n; i++)
node[i].succ = &node[i + 1];
for (int i = 2; i <= n; i++)
node[i].prec = &node[i - 1];
for (int i = 1; i <= n; i++)
c[a[i]] = i;
int ans = 1;
for (int j = 1; j <= m; j++)
{
int i = c[b[j]];
Node *p = &node[i];
Node *prec = p->prec;
Node *succ = p->succ;
if (prec && f[prec->val] > j)
prec = NULL;
if (succ && f[succ->val] > j)
succ = NULL;
if (prec && succ)
{
ans *= 2;
ans %= mod;
deleteNode(prec);
}
else if (prec)
{
deleteNode(prec);
}
else if (succ)
{
deleteNode(succ);
}
else
{
cout << 0 << endl;
return;
}
}
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(false);
int t;
cin >> t;
while (t--)
{
solve();
}
}