题解:AT_abc457_f [ABC457F] Second Gap
计数好题!
先考虑
两个状态分别表示
表示
考虑优化。发现如果
那么我们全局乘法时打一个 tag,同时转移第一条的时候记录哪些位置不是
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fi first
#define se second
#define lowbit(x) ((x)&(-(x)))
const int N=3e5+10,mod=998244353;
int qpow(int a,int b)
{
int s=1;
while(b)
{
if(b&1) s=s*a%mod;
a=a*a%mod;
b>>=1;
}
return s;
}
int d[N];
int dp[N];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int n;
cin>>n;
for(int i=1;i<n;i++) cin>>d[i];
dp[n]=1;
int ss=1,is=1;
vector<int>vec;
vec.push_back(n);
for(int i=n-1;i>=1;i--)
{
int p=i+d[i];
int tx=dp[p];
if(i!=n-1&&d[i]==d[i+1])
{
ss=ss*(n-i-1)%mod;
is=is*qpow(n-i-1,mod-2)%mod;
tx=tx*qpow(n-i-1,mod-2)%mod;
}
else
{
for(auto v:vec) dp[v]=0;
vec.clear();
}
dp[i]=(dp[i]+tx)%mod;
dp[p]=(dp[p]+tx)%mod;
vec.push_back(i);
vec.push_back(p);
}
int ans=0;
for(int i=1;i<=n;i++) ans=(ans+dp[i])%mod;
cout<<ans*ss%mod;
return 0;
}
:::