Loading

题解-CF1140E Palindrome-less Arrays

CF1140E Palindrome-less Arrays

\(n\)\(k\)\(n\) 个数的序列 \(a\)。把 \(a\) 中的 \(-1\) 替换成 \([1,k]\) 之间的整数。求使 \(a\) 中不存在长度为奇数的回文串的方案数。

数据范围:\(2\le n,k\le 2\cdot 10^5\)\(a_i=-1{\rm~or~}a_i\in[1,k]\)


题目限制即不能有 \(a_i=a_{i-2}\)

\(b_i=a_{2i},c_i=a_{2i-1}\)

答案为序列 \(b\)\(c\) 填成相邻两数不等的方案数积


如填 \(x,-1,-1,...,-1,y\) 这段 \(i\)\(-1\) 使相邻两数不等:

\(f_i\) 表示 \(x=y\) 的填法方案数,\(g_i\) 表示 \(x\not=y\) 的填法方案数。

\[f_i= \begin{cases} 0&(i=0)\\ g_{i-1}(k-1)&{\rm else}\\ \end{cases}\\\\ g_i= \begin{cases} 1&(i=0)\\ g_{i-1}(k-2)+f_{i-1}&{\rm else}\\ \end{cases} \]

最后把每段 \(-1\) 的答案乘起来就是填 \(b,c\) 的方案数。

边界的处理具体看代码。


  • 代码
#include <bits/stdc++.h>
using namespace std;

//Start
typedef long long ll;
typedef double db;
#define mp(a,b) make_pair(a,b)
#define x first
#define y second
#define b(a) a.begin()
#define e(a) a.end()
#define sz(a) int((a).size())
#define pb(a) push_back(a)
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;

//Data
const int N=2e5;
const int mod=998244353;
int n,k,a[N+7];

//DP
int f[2][(N<<1)+7]; 
int bb,b[(N>>1)+7],cc,c[(N>>1)+7];
void Pre(){
	f[0][0]=0,f[1][0]=1;
	for(int i=1;i<=(n>>1)+1;i++){
		f[0][i]=(ll)f[1][i-1]*(k-1)%mod;
		f[1][i]=((ll)f[1][i-1]*(k-2)%mod+f[0][i-1])%mod;
	}
}
int DP(int cnt,int s[]){
	int len=0,lst=0,res=1;
	for(int i=1;i<=cnt;i++){
		if(s[i]==-1) len++;
		else {
			if(len){
				if(!lst) res=(ll(k-1)*f[1][len-1]+f[0][len-1])%mod*res%mod;
				else if(lst==s[i]) res=(ll)f[0][len]*res%mod;
				else res=(ll)f[1][len]*res%mod;
			}
			len=0,lst=s[i];
		}
	}
	if(len){
		if(!lst){
			if(len==1) res=k;
			else res=(ll(k-1)*f[1][len-2]+f[0][len-2])*k%mod*res%mod;
		} else res=(ll(k-1)*f[1][len-1]+f[0][len-1])%mod*res%mod;
	}
	return res;
}

//Main
int main(){
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		if(~a[i]&&i-2>=1&&a[i]==a[i-2]) return puts("0"),0;
		if(i&1) c[++cc]=a[i];
		else b[++bb]=a[i];
	}
	Pre();
	printf("%d\n",(ll)DP(cc,c)*DP(bb,b)%mod);
	return 0;
}


祝大家学习愉快!

posted @ 2020-05-26 15:41  George1123  阅读(175)  评论(0编辑  收藏  举报