Polarisx
2024-11-18 17:01:04
题目传送门。
啊。简单题。
首先很容易发现连通块一定是以区间形式呈现在该序列上的,这个是容易证明的:
对于点
综上,
此时对于一个序列,连通块数等于分割点数量加
考虑枚举这些分割点,假设为
记
时间复杂度
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int Mod=998244353;
const int Maxn=2010;
int n,m;
int b[Maxn],pre[Maxn],suf[Maxn];
int pmn[Maxn],pmx[Maxn];
ll gmin[Maxn],gmax[Maxn];
inline ll ksm(ll a,int b,int mod){
ll z=1;
while(b){
if(b&1) z=z*a%mod;
a=a*a%mod;
b>>=1;
}
return z;
}
ll ans;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&b[i]);
pmn[0]=m;
for(int i=1;i<=n;i++){
if(b[i]==-1) pmn[i]=pmn[i-1];
else pmn[i]=min(pmn[i-1],b[i]);
}
for(int i=n;i;i--){
if(b[i]==-1) pmx[i]=pmx[i+1];
else pmx[i]=max(pmx[i+1],b[i]);
}
for(int i=1;i<=n;i++) pre[i]=pre[i-1]+(b[i]==-1);
for(int i=n;i;i--) suf[i]=suf[i+1]+(b[i]==-1);
for(int p=1;p<=n;p++){
for(int j=1;j<=m;j++) gmin[j]=gmax[j]=0;
for(int j=1;j<=pmn[p];j++) gmin[j]=ksm(m-j+1,pre[p],Mod);
for(int j=pmx[p+1];j<=m;j++) gmax[j]=ksm(j,suf[p+1],Mod);
for(int j=2;j<=m;j++) ans=(ans+gmin[j]*(gmax[j-1]-gmax[j-2])%Mod)%Mod;
}
ans=(ans+ksm(m,pre[n],Mod))%Mod;
ans=(ans%Mod+Mod)%Mod;
printf("%lld",ans);
system("pause");
return 0;
}