不难发现一个性质,若对于
Ai−1
A
i
−
1
的限制是
Li−1≤Ai−1≤Ri−1
L
i
−
1
≤
A
i
−
1
≤
R
i
−
1
,对于
Ai
A
i
的限制是
Li≤Ai≤Ri
L
i
≤
A
i
≤
R
i
,那么有
Li−1≤Li
L
i
−
1
≤
L
i
,
Ri−1≥Ri
R
i
−
1
≥
R
i
,于是我们考虑DP。
设
fi,x,l,r
f
i
,
x
,
l
,
r
表示填了
i
i
个数,为
x
x
,中
≤x
≤
x
的最大值是
l
l
,的最小值是
r
r
(注意不是限制
Ai
A
i
的范围)的方案数。
对于
x,l,r
x
,
l
,
r
互不相等的状态,
Ai−1
A
i
−
1
必然充当了
l
l
或者,转移就是
fi,x,l,r←∑k≤lfi−1,l,k,r+∑k≥rfi−1,r,l,k
f
i
,
x
,
l
,
r
←
∑
k
≤
l
f
i
−
1
,
l
,
k
,
r
+
∑
k
≥
r
f
i
−
1
,
r
,
l
,
k
。
对于
x,l,r
x
,
l
,
r
只有两者相等的状态显然是不存在的。
对于
x,l,r
x
,
l
,
r
全相等的状态需要特殊处理,因为
Ai−1
A
i
−
1
不一定充当了
l
l
或,可能是之前一个
=x
=
x
的数充当了两者,所以讨论两种情况:
1.
Ai−1=x
A
i
−
1
=
x
,这时
fx,x,x←∑j≤x∑k≥xfi−1,x,j,k
f
x
,
x
,
x
←
∑
j
≤
x
∑
k
≥
x
f
i
−
1
,
x
,
j
,
k
。
2.
Ai−1≠x
A
i
−
1
≠
x
,这时
fx,x,x←∑y≠x(∑k≤yfi−1,y,k,x+∑k≥yfi−1,y,x,k)
f
x
,
x
,
x
←
∑
y
≠
x
(
∑
k
≤
y
f
i
−
1
,
y
,
k
,
x
+
∑
k
≥
y
f
i
−
1
,
y
,
x
,
k
)
。
然后用前缀和维护一些
∑k≤x,∑k≥x
∑
k
≤
x
,
∑
k
≥
x
什么的就可以把复杂度降到
O(nmax3{ai})
O
(
n
max
3
{
a
i
}
)
了。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#define ui unsigned int
using namespace std;
const int mod=998244353;
ui n,r[55],mxr,f[155][155][155],sl[155][155][155],sr[155][155][155];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&r[i]);
mxr=max(mxr,r[i]+1);
}
for(int i=0;i<=mxr;i++)
sl[0][i][mxr]=sr[0][0][i]=1;
for(int i=1;i<=n;i++)
{
memset(f,0,sizeof(f));
for(int ai=1;ai<=r[i];ai++)
{
for(int L=0;L<ai;L++)
for(int R=ai+1;R<=mxr;R++)
f[ai][L][R]=(sl[L][L][R]+sr[R][L][R])%mod;
for(int R=ai;R<=mxr;R++)
f[ai][ai][ai]=(f[ai][ai][ai]+sl[ai][mxr][R])%mod;
for(int ai_1=0;ai_1<=mxr;ai_1++)
if(ai_1!=ai)
f[ai][ai][ai]=(f[ai][ai][ai]+sl[ai_1][ai_1][ai]+sr[ai_1][ai][ai_1])%mod;
}
memset(sl,0,sizeof(sl));
for(int ai=1;ai<=r[i];ai++)
for(int L=0;L<=mxr;L++)
for(int R=ai;R<=mxr;R++)
sl[ai][L][R]=(f[ai][L][R]+(L==0?0:sl[ai][L-1][R]))%mod;
memset(sr,0,sizeof(sr));
for(int ai=1;ai<=r[i];ai++)
for(int L=0;L<=ai;L++)
for(int R=mxr;R>=0;R--)
sr[ai][L][R]=(f[ai][L][R]+sr[ai][L][R+1])%mod;
}
ui ans=0;
for(int ai=1;ai<=r[n];ai++)
for(int L=0;L<=ai;L++)
for(int R=ai;R<=mxr;R++)
ans=(ans+f[ai][L][R])%mod;
printf("%d",ans);
return 0;
}