题解:CF1906J Count BFS Graph
Solution
bfs 按层进行,每个点能 push 进去一段点。设
那么
前面这
整理一下就是
这样直接做是三次方的,然后你注意到一个转移是区间加一个固定的数,所以前缀和 + 差分即可,时间复杂度
Code
#include<algorithm>
#include<iostream>
#include<cstdio>
#define file(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
using namespace std;
typedef long long ll;
namespace FastIO{
template<typename T=int> T read(){
T x=0;int f=1;char c=getchar();
while(!isdigit(c)){if(c=='-') f=~f+1;c=getchar();}
while(isdigit(c)){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
template<typename T> void write(T x){
if(x<0){putchar('-');x=-x;}
if(x>9) write(x/10);
putchar(x%10+'0');
}
template<typename T> void Write(T x,char c='\n'){write(x);putchar(c);}
}
using namespace FastIO;
const int MOD=998244353;
const int maxn=5005;
int f[maxn][maxn],pw[maxn],r[maxn],a[maxn],c[maxn];
int main(){
int n=read();
f[1][1]=1;pw[0]=1;
for(int i=1;i<=n;i++) pw[i]=(pw[i-1]*2)%MOD;
for(int i=1;i<=n;i++) a[r[i]=i]=read();
for(int i=1;i<=n;i++) while(a[r[i]]<a[r[i]+1]) r[i]++;
r[n+1]=n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++) c[j]=0;
for(int j=i;j<=n;j++){
// for(int k=j;k<=r[j+1];k++){
// (f[i+1][k]+=(1ll*pw[j-i]*f[i][j])%MOD)%=MOD;
// printf("%d %d %d\n",i,j,f[i][j]);
// }
int x=(1ll*pw[j-i]*f[i][j])%MOD;
c[j]=(c[j]+x)%MOD,c[r[j+1]+1]=(c[r[j+1]+1]-x+MOD)%MOD;
}
for(int j=1;j<=n;j++) c[j]=(c[j]+c[j-1])%MOD;
for(int j=i;j<=n;j++) f[i+1][j]=c[j];
}
write(f[n+1][n]);
return 0;
}