思路
- 做法:找到每一个b中每一个值的最后一个所在的索引,b中每一个值的最后一个索引必须在第i个区间,也就是如果a中有多个b[i],那么这些b[i]的最后一个b[i]必须在第i个区间,因为b是升序的,如果不在同一个区间会影响后面的区间的最小值,那么从b[i]的最后一个索引位置一直到最后一个小于b[i-1]的位置,这个区间的数字是可以变化的,也就是可以存入b[i-1]的区间,也可以留在b[i]区间,就是下图
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200612153252417.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTA4MDg2Nw==,size_16,color_FFFFFF,t_70)
- 把所有每个区间这些数的个数相乘即可,当然,还要判断一下区间能所有的点是不是满足大于这个区间的最小值。
代码
#include <cstring>
#include <algorithm>
#include <iostream>
#include <map>
using namespace std;
typedef long long ll;
const int N=2e5+5;
const int MOD= 998244353;
ll a[N];
ll b[N];
map<ll,ll> mp;
int m,n;
int main(){
cin >> n >> m;
ll res=1;
for(int i=0;i<n;i++)cin >> a[i];
for(int i=0;i<m;i++)cin >> b[i];
for(int i=0;i<n;i++){
mp[a[i]]=i;
}
ll idx=0;
for(int i=0;i<m;i++){
if(!mp.count(b[i])||idx>mp[b[i]]){
cout << 0 << "\n";
return 0;
}
if(i==0){
while(idx<=mp[b[i]]){
if(a[idx]<b[i]){
cout << 0 << "\n";
return 0;
}
idx++;
}
}
else{
ll tmp=mp[b[i-1]];
while(idx<mp[b[i]]){
if(a[idx]<b[i-1]){
cout << 0 << "\n";
return 0;
}
if(a[idx]<b[i]){
tmp=idx;
}
idx++;
}
res=(res*((mp[b[i]]-tmp)%MOD))%MOD;
}
}
while(idx<n){
if(a[idx]<b[m-1]){
cout << 0 << "\n";
return 0;
}
idx++;
}
cout << res << "\n";
}