cf1093F(计数dp)

题意:给长度为n的序列,要填充-1,使得不出现长度为m的元素相同的子串(下称非法子串),其中数字的范围均在1-k

一开始想的是O(n)的做法,只对每个-1的段进行考虑,然后各种挂,最后发现相邻的-1的段会相互影响,然后就绝望了。。

然后只能向O(nk)的方法低头了。。这个就比较简单了,设d[i][j]为第i位填j的方案数,然后如果[i-m+1,i]能形成相同的元素,那么做个容斥就能把非法情况去掉了,即把d[i-m]中和当前元素不相同的状态去掉。。

 

 

/**
 *          ┏┓    ┏┓
 *          ┏┛┗━━━━━━━┛┗━━━┓
 *          ┃       ┃  
 *          ┃   ━    ┃
 *          ┃ >   < ┃
 *          ┃       ┃
 *          ┃... ⌒ ...  ┃
 *          ┃              ┃
 *          ┗━┓          ┏━┛
 *          ┃          ┃ Code is far away from bug with the animal protecting          
 *          ┃          ┃   神兽保佑,代码无bug
 *          ┃          ┃           
 *          ┃          ┃        
 *          ┃          ┃
 *          ┃          ┃           
 *          ┃          ┗━━━┓
 *          ┃              ┣┓
 *          ┃              ┏┛
 *          ┗┓┓┏━━━━━━━━┳┓┏┛
 *           ┃┫┫       ┃┫┫
 *           ┗┻┛       ┗┻┛
 */ 
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<map>
#include<stack>
#include<cmath>
#include<set>
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,l,r) for(int i=l;i>=r;i--)
#define link(x) for(edge *j=h[x];j;j=j->next)
#define mem(a) memset(a,0,sizeof(a))
#define ll long long
#define eps 1e-8
#define succ(x) (1<<x)
#define lowbit(x) (x&(-x))
#define sqr(x) ((x)*(x))
#define mid (x+y>>1)
#define NM 100005
#define nm 2005
#define pi 3.1415926535897931
const int inf=998244353;
using namespace std;
ll read(){
    ll x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}
 
 







int n,m,p,a[NM],cnt[105];
ll _s,s,d[NM][105];

int main(){
    n=read();m=read();p=read();
    inc(i,1,n)a[i]=read();
    d[0][0]=1;a[0]=m+1;
    inc(i,1,n){
	if(i>=p){
	    cnt[a[i-p]]--;_s=0;
	    inc(j,0,m)_s+=d[i-p][j],_s%=inf;
	}
	s=0;
	inc(j,0,m)s+=d[i-1][j],s%=inf;
	if(a[i]==-1){
	    a[i]=0;
	    cnt[0]++;
	    inc(j,1,m){
		d[i][j]=s;
		if(cnt[0]+cnt[j]==p)d[i][j]+=inf-_s+d[i-p][j],d[i][j]%=inf;
	    }
	}else{
	    cnt[a[i]]++;
	    d[i][a[i]]=s;
	    if(cnt[0]+cnt[a[i]]==p)d[i][a[i]]+=inf-_s+d[i-p][a[i]],d[i][a[i]]%=inf;
	}
    }
    s=0;inc(i,1,m)s+=d[n][i],s%=inf;
    return 0*printf("%lld\n",s);
}

 

 

 

 

 

F. Vasya and Array

time limit per test

2 seconds

memory limit per test

512 megabytes

input

standard input

output

standard output

Vasya has got an array consisting of ?

integers, and two integers ? and ??? in addition. All numbers in the array are either between 1 and ? (inclusive), or equal to −1. The array is good if there is no segment of ???

consecutive equal numbers.

Vasya will replace each −1

with some number from 1 to ? (inclusive) in such a way that the resulting array is good. Tell him the number of ways to do this replacement. Since the answer may be large, print it modulo 998244353

.

Input

The first line contains three integers ?,?

and ??? (1≤?≤105,1≤?≤100,1≤???≤?

).

The second line contains ?

numbers — the array. Each number is either −1 or between 1 and ?

(inclusive).

Output

Print one integer — the number of ways to replace each −1

with some number from 1 to ? (inclusive) so the array is good. The answer may be large, so print it modulo 998244353

.

Examples

Input

Copy

5 2 3
1 -1 1 -1 2

Output

Copy

2

Input

Copy

6 3 2
1 1 -1 -1 -1 -1

Output

Copy

0

Input

Copy

10 42 7
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1

Output

Copy

645711643

Note

Possible answers in the first test:

  1. [1,2,1,1,2]
  • ;
  • [1,2,1,2,2]
  1. .

There is no way to make the array good in the second test, since first two elements are equal.

There are too many answers in the third test, so we won't describe any of them.

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值