Wavel Sequence
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 986 Accepted Submission(s): 492
Problem Description
Have you ever seen the wave? It's a wonderful view of nature. Little Q is attracted to such wonderful thing, he even likes everything that looks like wave. Formally, he defines a sequence a1,a2,...,an as ''wavel'' if and only if a1<a2>a3<a4>a5<a6...
Picture from Wikimedia Commons
Now given two sequences a1,a2,...,an and b1,b2,...,bm, Little Q wants to find two sequences f1,f2,...,fk(1≤fi≤n,fi<fi+1) and g1,g2,...,gk(1≤gi≤m,gi<gi+1), where afi=bgi always holds and sequence af1,af2,...,afk is ''wavel''.
Moreover, Little Q is wondering how many such two sequences f and g he can find. Please write a program to help him figure out the answer.
Input
The first line of the input contains an integer T(1≤T≤15), denoting the number of test cases.
In each test case, there are 2 integers n,m(1≤n,m≤2000) in the first line, denoting the length of a and b.
In the next line, there are n integers a1,a2,...,an(1≤ai≤2000), denoting the sequence a.
Then in the next line, there are m integers b1,b2,...,bm(1≤bi≤2000), denoting the sequence b.
Output
For each test case, print a single line containing an integer, denoting the answer. Since the answer may be very large, please print the answer modulo 998244353.
Sample Input
1
3 5
1 5 3
4 1 1 5 3
Sample Output
10
Hint
简单的二维bits,对于每一位可以选的值,在二维树状数组中找到和更新满足的值,维护两个二维树状数组,一个是最后一个值是上升的,一个是最后一个值是下降的
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 998244353;
const int maxn = 1e5+9;
int a[maxn],b[maxn];
int n,m;
ll bit1[2009][2009],bit2[2009][2009];
ll Query1(int j,int x){
ll ans=0;
while(x){
ans=(ans+bit1[j][x])%mod;
x-=(x&-x);
}
return ans;
}
ll query1(int j,int x){
ll ans=0;
while(j){
ans=(ans+Query1(j,x))%mod;
j-=(j&-j);
}
return ans;
}
ll Query2(int j,int x){
ll ans=0;
while(x){
ans=(ans+bit2[j][x])%mod;
x-=(x&-x);
}
return ans;
}
ll query2(int j,int x){
ll ans=0;
while(j){
ans=(ans+Query2(j,x))%mod;
j-=(j&-j);
}
return ans;
}
void Add1(int j,int x,ll y){
while(x<=2000){
bit1[j][x]=(bit1[j][x]+y)%mod;
x+=(x&-x);
}
}
void add1(int j,int x,ll y){
while(j<=m){
Add1(j,x,y);
j+=(j&-j);
}
}
void Add2(int j,int x,ll y){
while(x<=2000){
bit2[j][x]=(bit2[j][x]+y)%mod;
x+=(x&-x);
}
}
void add2(int j,int x,ll y){
while(j<=m){
Add2(j,x,y);
j+=(j&-j);
}
}
int main(){
int t;scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i=0;i<=2000;i++){
for(int j=0;j<=2000;j++){
bit1[i][j]=bit2[i][j]=0;
}
}
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++){
for(int j=1;j<=m;j++){
if(a[i]==b[j]){
ans=(ans+1)%mod;
ll x=query1(j,a[i]-1);
ll y=(query2(j,2000)-query2(j,a[i])+mod)%mod;
ans=(ans+x+y)%mod;
add1(j,a[i],y+1);
add2(j,a[i],x);
}
}
}
printf("%lld\n",ans);
}
return 0;
}