题意:给你a,b两个序列,想要找出两个序列f,g(均为递增序列),使 afi=bgi ,且 af1,af2......afn 是波浪型},计算·有多少种f,g序列。
题解:固定
ai
,去找
bi
,只需要考虑相等的情况,不相等的情况只需要相加就好了。
波浪一定会有波峰和波谷,如果对于一个
ai
来说,如果在b中只有一个数字与他相等,那只有以
ai
为波谷或者在之前出现以
ai
为波峰的情况。所以整体思路就是寻找每一个
ai=bi
的情况,顺便考虑与前面能形成波浪的情况。
(代码还是比较好懂的)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=20005;
const int mod=998244353;
ll dp[maxn][2],sum[maxn][2];
int n,m;
int a[maxn],b[maxn];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(dp,0,sizeof dp);
memset(sum,0,sizeof sum);
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=m;i++)
scanf("%d",&b[i]);
ll ans=0;
for(int i=1;i<=n;i++)
{
int p=1,v=0;
for(int j=1;j<=m;j++)
{
if(a[i]==b[j])
{
dp[j][0]=p;
dp[j][1]=v;
ans=(ans+p+v)%mod;
}
else if(a[i]>b[j])
{
v=(v+sum[j][0])%mod;
}
else if(a[i]<b[j])
{
p=(p+sum[j][1])%mod;
}
}
for(int j=1;j<=m;j++)
{
if(a[i]==b[j])
{
sum[j][0]=(sum[j][0]+dp[j][0])%mod;
sum[j][1]=(sum[j][1]+dp[j][1])%mod;
}
}
}
printf("%lld\n",ans);
}
}