CodeForces 1093F Vasya and Array

题意

给一个长度为 \(n\) 的整数序列 \(a\),其中 \(a_i\) 要么为 \(-1\),要么为 \(1\sim k\) 中的整数。

求出将所有 \(-1\) 替换为 \(1\sim k\) 中整数的方案数,满足替换后的序列中不存在连续 \(l\) 个相同的数,对 \(998244353\) 取模。

\(\texttt{Data Range:}1\leq l\leq n\leq 10^5,1\leq k\leq 100\)

题解

注意到 \(k\) 的范围很小,可以设一个 \(f_{i,j}\) 表示第 \(i\) 个位置的数字为 \(j\) 的时候前缀的方案数,再记一个 \(s_i=\sum f_{i,j}\)

首先注意到只有 \(a_i=-1\) 或者 \(a_i=j\) 的时候 \(f_{i,j}\) 才可能被转移到。

于是考虑设 \(len_{i,j}\) 表示以 \(i\) 为后缀最多连续的 \(j\) 的个数。

\(len_{i,j}<l\) 的时候 \(f_{i,j}=s_{i-1}\)

否则因为可以在这段后缀中填出大于等于 \(l\) 的,要减掉不合法的方案数,为 \(s_{i-l}-f_{i-l,j}\)

代码

#include<bits/stdc++.h>
using namespace std;
typedef int ll;
typedef long long int li;
const ll MAXN=2e5+51,MOD=998244353;
ll n,kk,l,p;
ll x[MAXN],f[MAXN][101],len[MAXN][101],s[MAXN];
inline ll read()
{
    register ll num=0,neg=1;
    register char ch=getchar();
    while(!isdigit(ch)&&ch!='-')
    {
        ch=getchar();
    }
    if(ch=='-')
    {
        neg=-1;
        ch=getchar();
    }
    while(isdigit(ch))
    {
        num=(num<<3)+(num<<1)+(ch-'0');
        ch=getchar();
    }
    return num*neg;
}
int main()
{
    n=read(),kk=read(),l=read(),s[0]=1;
    if(l==1)
    {
        return puts("0"),0;
    }
    for(register int i=1;i<=n;i++)
    {
        x[i]=read();
        for(register int j=1;j<=kk;j++)
        {
            len[i][j]=len[i-1][j]+(x[i]==-1||x[i]==j);
        }
    }
    if(x[1]==-1)
    {
        for(register int i=1;i<=kk;i++)
        {
            f[1][i]=1;
        }
        s[1]=kk;
    }
    else
    {
        f[1][x[1]]=1,s[1]=1;
    }
    for(register int i=2;i<=n;i++)
    {
        for(register int j=1;j<=kk;j++)
        {
            if(x[i]==-1||x[i]==j)
            {
                f[i][j]=s[i-1];
                if(i>=l)
                {
                    p=i-l;
                    if(len[i][j]-len[p][j]==l)
                    {
                        f[i][j]=((li)f[i][j]+f[p][j]-s[p]+MOD)%MOD;
                    }
                }
            }
            s[i]=(s[i]+f[i][j])%MOD;
        }
    }
    printf("%d\n",s[n]);
}
posted @ 2020-08-08 15:57  Karry5307  阅读(138)  评论(0编辑  收藏  举报